I have a node.js server that does an API request, the page should send as response the data I get from that api. The catch here is:
I need to do several calls to the api, put all the data together separated by an id e send that back as json to the client.
To create that request I have first to query my DB and get the data I have to send to the api After that I filter that data using array.filter and to create the requests, I am using array.map to call a function that deals with the request.
Code:
router.get('/', cors(), (req, res) =>{
const response = getListOfStatistics()
});
when I enter the page, the function getListOfStatistics()
is fired:
function getListOfStatistics(){
axios.get('http://localhost:4002/')
.then(response =>{
items = response.data
let result = filterStatistic(items)
return result;
//I wrote that return result when trying to give the data back
//So I could send it to the client as json
})
.catch(err =>{
console.log(err)
})
}
After getting the data from the db, I try filtering it:
function filterStatistic(items){
const jahreStatistic = items.filter(item => item.period == 0)
const virtelJahrStatistic = items.filter(item => item.period == 3)
//Both methods above are working
jahreStatistic.map(item => {
connection.statistic_id = item.statistic_id
var periods = getReportingPeriod(item.period)
for(let i=0; i < 3; i++){
switch(i){
case 0:
connection.reporting_period = periods.prevYear
preOrderedObjects.Jahr = sendHTTPRequest(item)
break;
case 1:
connection.reporting_period = periods.actualYear
preOrderedObjects.Jahr = sendHTTPRequest(item)
break;
case 2:
connection.reporting_period = periods.nextYear
preOrderedObjects.Jahr = sendHTTPRequest(item)
break;
}
}
})
}
function sendHTTPRequest (item){
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'https://externalapi/api/',
form: connection
},
(err, response, body) => {
if(response.headers['x-status'])
{
info.name = item.name
info.evas = item.evas
info.id = item.statistic_id
info.link = item.link
info.resourceID = response.headers['x-resourceid'];
info.fileName = response.headers['x-filename'];
console.log(info.name) //This shows that my three requests
were made.
**if(item.period==0){
//Evas is a global array evas = []
//info is a global object info = {}
evas.push(info)
//My goal was to push each request to this array and
//return it to after, add to another object.
//This does not work.
return evas**
}else{
ids.push(info)
preOrderedObjects.Jahr = ids
}
}
})
}
I would like to get all the data pushed to the evas array and then added to my preOrderedObjects.Jahr
After, at the end, I want to return that to the client as json
Anyone has an idea of what I am missing and how to maybe fix that?
You need to convert your getListOfStatistics
function into a callback function . You are making a GET request to another server using promises (we can say a better version of callbacks) and the result might take a while to have a value.
The callback will return the result
variable once it has a value.
function getListOfStatistics(callback){
axios.get('http://localhost:4002/')
.then(response =>{
items = response.data
let result = filterStatistic(items)
callback(result);
})
.catch(err =>{
console.log(err)
})
}
To execute getListOfStatistics
, you will need to pass a function as a parameter, like this:
let response;
getListOfStatistics(function(result)){
response = result;
}
Note that response
must be a variable and it will have a value once the callback is finished.
Same goes for sendHTTPRequest
method, you will need to convert it too since you want all requests to finish. However using Evas
and preOrderedObjects
as global variables don't look like a good idea, but anyways.
function filterStatistic(items, callback){
const jahreStatistic = items.filter(item => item.period == 0)
const virtelJahrStatistic = items.filter(item => item.period == 3)
//Both methods above are working
jahreStatistic.map(item => {
connection.statistic_id = item.statistic_id
var periods = getReportingPeriod(item.period)
for(let i=0; i < 3; i++){
switch(i){
case 0:
connection.reporting_period = periods.prevYear
sendHTTPRequest(item, function(result){
preOrderedObjects.Jahr = result
})
break;
case 1:
connection.reporting_period = periods.actualYear
sendHTTPRequest(item, function(result){
preOrderedObjects.Jahr = result
})
break;
case 2:
connection.reporting_period = periods.nextYear
sendHTTPRequest(item, function(result){
preOrderedObjects.Jahr = result
})
break;
}
}
})
}
function sendHTTPRequest (item, callback){
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'https://externalapi/api/',
form: connection
},
(err, response, body) => {
if(response.headers['x-status'])
{
info.name = item.name
info.evas = item.evas
info.id = item.statistic_id
info.link = item.link
info.resourceID = response.headers['x-resourceid'];
info.fileName = response.headers['x-filename'];
console.log(info.name) //This shows that my three requests
were made.
**if(item.period==0){
evas.push(info)
callback(evas)
}else{
ids.push(info)
preOrderedObjects.Jahr = ids
}
}
})
}
Well, for starters you can try to change the request headers to: 'application/json'.
As for the requests, they are async, so you cannot get the result immediately, you can turn the getListOfStatistics into a callback or call the async/await trick on the function as follows:
function getListOfStatistics(){
axios.get('http://localhost:4002/')
.then(async (response) =>{
items = response.data
let result = await filterStatistic(items);
return result;
})
.catch(err =>{
console.log(err)
});
As for that switch/case, you are also making http async requests, you can use the async await method OR you can push the requests into a promise array and resolve them all at once:
let requests = [];
jahreStatistic.map(item => {
connection.statistic_id = item.statistic_id
var periods = getReportingPeriod(item.period)
for(let i=0; i < 3; i++){
switch(i){
case 0:
connection.reporting_period = periods.prevYear
requests.push(sendHTTPRequest(item));
break;
case 1:
connection.reporting_period = periods.actualYear
requests.push(sendHTTPRequest(item));
break;
case 2:
connection.reporting_period = periods.nextYear
requests.push(sendHTTPRequest(item));
break;
}
}
})
}
Promise.all(requests).then((results) => {
// do some work here
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.