I have an asynchronous function that is called when the api is connected to. this should return some json and then it will be displayed on the json response of the page. In the json response I get undefined.
This is the code i am using:
const express = require('express');
const router = express.Router();
const superagent = require('superagent');
function getCyrpto(){
var result;
superagent.get('https://min-api.cryptocompare.com/data/v2/pair/mapping/exchange?e=Kraken')
.query({ api_key: 'xxxxxxxx'})
.end((err, res) => {
if (err) { return console.log(err); }
result = res.body;
});
setTimeout(() => {
console.log(result);
return result;
}, 2000)
}
router.get('/', (req, res, next) => {
crypto=getCyrpto()
setTimeout(()=> {
res.status(200).json({
message: 'geting cyrpto',
apiResponse: crypto
});
}, 2500)
});
The reason it is happeing because your setTimeOut methods runs before your api call get the result and assign it to the result
.
This is a common problem most of us face when we start to learn concurrency concept.
For example:
console.log("a");
setTimeOut(()=>console.log("b"),1000);
console.log("c");
Output of above function will
a
c
b
this is happening beacause setTimeout function is a promise which means your nodejs will not wait for it to finish before running the next line, it will just process the setTimeout function in background and when it will finish it will call its callback function given as first parameter in setTimeOut.
Your solution should be
function getCyrpto(){
return new Promise((resolve,reject)=>{
var result;
superagent.get('https://min-api.cryptocompare.com/data/v2/pair/mapping/exchange?e=Kraken')
.query({ api_key: 'xxxxxxxx'})
.end((err, res) => {
if (err) { console.log(err); reject(err); }
result = res.body;
setTimeout(() => {
console.log(result);
resolve(result);
}, 2000)
});
}
router.get('/', (req, res, next) => {
getCyrpto().then(crypto=>{
setTimeout(()=> {
res.status(200).json({
message: 'geting cyrpto',
apiResponse: crypto
},2500);
}).catch(err=>{res.status(400).json(err)})
}