Home > Net >  JavaScript: out of scope variable leads to an error
JavaScript: out of scope variable leads to an error

Time:11-17

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.

  • Related