A rather primitive question, but I can't find how to solve it:
I have an array initiated and in this scope and I need to push an object from a JSON (which got transformed from a XML) into a data array, which collects the data in a loop and I need to only then return the response out of scope, because in the scope it is not full yet.
How do I solve this rather primitive problem?
My minimal example looks like this:
{
...
dataarr.push(jsonObj['soap:Envelope']['soap:Body']['ns:Response']['return']['items']);
} // scope 1 ends here
res.status(200).send(dataarr); // out of scope in this scope 2 the response has to be sent back to the client
I get the error because the variable is out of scope, how do I fix this though?
UPDATE 1
More code:
let dataarr = [];
let payloadarr = [];
...
axios(config)
.then(function (response) {
logger.log('info', 'POST /getdata successful from ' req.ip);
var options = {
attributeNamePrefix : "@_",
attrNodeName: "attr", //default is 'false'
textNodeName : "#text",
ignoreAttributes : true,
ignoreNameSpace : false,
allowBooleanAttributes : false,
parseNodeValue : true,
parseAttributeValue : false,
trimValues: true,
cdataTagName: "__cdata", //default is 'false'
cdataPositionChar: "\\c",
parseTrueNumberOnly: false,
arrayMode: false, //"strict"
attrValueProcessor: (val, attrName) => he.decode(val, {isAttributeValue: true}),//default is a=>a
tagValueProcessor : (val, tagName) => he.decode(val), //default is a=>a
stopNodes: ["parse-me-as-string"]
};
console.log("response.data:");
console.log(response.data);
if( parser.validate(response.data) === true) { //optional (it'll return an object in case it's not valid)
var jsonObj = parser.parse(response.data,options);
}
var tObj = parser.getTraversalObj(response.data,options);
var jsonObj = parser.convertToJson(tObj,options);
console.log("jsonObj in parsing:");
console.log(jsonObj);
console.log(jsonObj['soap:Envelope']['soap:Body']['ns:getResponse']['return']['items']);
dataarr.push(jsonObj['soap:Envelope']['soap:Body']['ns:getResponse']['return']['items']);
console.log("dataarr getting filled:");
console.log(j);
console.log(dataarr);
})
.catch(function (error) {
logger.warn('[/getdocumentmetadata]: ', new Error(error));
//console.log(error);
});
}
})
.catch(function (error) {
logger.warn('[GET /getdocuments]: ', new Error(error));
});
res.status(200).send(dataarr);
});
CodePudding user response:
There are 2 ways of doing it. You can either use await
to wait for each result or you can use Promise.all
to run them asynchronously and wait for the final result.
Option 1
let dataArr = [];
for(...){
const myData= await axios(config).then(res => {
var jsonObject = parse(res);
return jsonObject;
}).catch(...);
dataArr.push(myData)
}
res.status(200).send(dataArr);
Option 2
let promises = [];
for(){
promises.push(axios(config).then(res => {
var jsonObject= parse(res);
return jsonObject;
})
.catch(...));
}
let dataArr = await Promise.all(promises);
res.status(200).send(dataArr);
CodePudding user response:
UPDATE 1
You don't await the axios call so the function is resolved before you filled dataarr.
let dataarr = [] // at the top of you function
...
await new Promise((resolve, reject) => axios(config)
.then(function (response) {
...
resolve()
})
.catch(function (error) {
...
Could you try with this ?
CodePudding user response:
At the top the response variable is called "response" and in the last line its suddenly "res". I see no deklaration for the variable called "res".
Are these two different variables or unfortunated copied code?
I hope that helps.