Reputation: 991
I've been hitting StackOverflow for the last 2 hours and I simply cannot figure out how I'm supposed to retrieve data from an API, store it in Mongo, and then transfer it to my view with express. I feel like I must have made some mistakes in how I'm manipulating the data. I'm relatively new to these concepts and I'd really appreciate some guidance about what the best practices are. I can currently store the information to my DB, but when I try to pass it back up to my route, the axios promise returns undefined. Api keys have been stripped out for this post. Can someone please lend a helping hand?
//pull in express
const express = require('express');
const bodyParser = require('body-parser');
const axios = require('axios');
const mongoose = require('mongoose')
//Connect to mongoDB
mongoose.connect('mongodb://test:[email protected]:39965/companies');
const db = mongoose.connection;
//Create Schema for the application to interact with MongoDB
const companySchema = mongoose.Schema({
domain:{
type: String
},
email:{
type: [String]
},
confidence: {
type: [Number]
},
create_date:{
type: Date,
default: Date.now
}
}, {collection: 'companies'});
const Company = mongoose.model('Company', companySchema);
//bodyparser middleware for reading form submission
var urlencodedParser = bodyParser.urlencoded({ extended: false });
//declare router as variable for index view
const index = express.Router();
const hunterKey = '&api_key=8bd4aaded349a5d9784d021c2767e5d23e66140f';
const hunterUrl = `https://api.hunter.io/v2/domain-search?domain=`;
const fullContactKey = `&apiKey=f71cc6c7ccaa28f1`
const fullContactUrl = 'https://api.fullcontact.com/v2/company/lookup?domain=';
function outputHunter(response, res) {
let comp = response;
let em = [];
let c = [];
for (var i = 0; i < comp.emails.length; i++) {
//email arrays
// console.log(comp.emails[i].value);
em[i] = comp.emails[i].value;
c[i] = comp.emails[i].confidence;
}
var data = new Company({
domain: comp.domain,
email: em,
confidence: c
});
//console.log(data);
var CompanyData = Company(data).save((err, data) => {
if (err) throw err;
});
return data;
}
function searchHunter(searchVal, res) {
var CompanyData;
axios.get(hunterUrl + searchVal + hunterKey)
.then(function (response) {
response = outputHunter(response.data.data, res);
CompanyData = response;
})
.catch(function (error) {
console.error(error); throw error;
});
}
//use declare router for http methods
//get request for index with request, response, next params
index.get('/', function (req, res) {
//render response from server using index view from declared path in app.js
res.render('home', {
title: "Networkerr home",
body:
{
description: 'The Place to Network',
}
});
});
index.get('/:id', (req, res, next) => {
CompanyData.find()
.then(function(doc) {
res.render('company', {company: doc});
});
});
index.post('/submit', urlencodedParser, (req, res, next) => {
// console.log(req.body);
let data = searchHunter(req.body.domain, res);
console.log('fired')
console.log(data)
res.redirect('/' + data._id, {company: data});
});
module.exports = index;
Upvotes: 0
Views: 1549
Reputation: 3488
Some quick fixes:
I guess that in index.get('/:id',...
you dont need the next
parameter as well as in index.post('/submit',...
since they are routes, not middlewares.
In the index.get('/:id',...
, you need to a) fetch the right route parameter and call the right mongoose method (findById
)
index.get('/:id', (req, res) => {
CompanyData.findById(req.params.id) // <== Specify your id here
.then((doc) => {
..
});
});
the submit:
Saving the doc in the DB is an asynchronous task (fetch the data from hunter, and save it into the DB)
index.post('/submit', urlencodedParser, (req, res, next) => {
// console.log(req.body);
searchHunter(req.body.domain)
.then(data => {
// here the Promise is resolved and the doc has been fetched and saved
console.log('doc fetched and saved');
console.log(data)
res.redirect('/' + data._id, {company: data});
});
console.log('fired but not fetched and saved');
});
Other modifications will imply that searchHunter
must return a Promise
function searchHunter(searchVal) {
var CompanyData;
// return the Promise, so we can know when it has finished
return axios.get(hunterUrl + searchVal + hunterKey)
.then(function (response) {
return outputHunter(response.data.data);
})
.catch(function (error) {
console.error(error); throw error;
});
}
As well as outputHunter
:
function outputHunter(response, res) {
let comp = response;
let em = [];
let c = [];
for (var i = 0; i < comp.emails.length; i++) {
//email arrays
// console.log(comp.emails[i].value);
em[i] = comp.emails[i].value;
c[i] = comp.emails[i].confidence;
}
var company = new Company({
domain: comp.domain,
email: em,
confidence: c
});
// return the Promise so we can know when the company has been saved
return company.save((err, data) => {
if (err) throw err;
return data;
});
// shorter, if you dont want to modify data or handle err here
// return company.save();
}
Upvotes: 1