Having trouble detecting if a portion of a response is undefined

I'm trying to parse an xml response and pull certain data, however sometimes the data simply isn't there, which returns a "TypeError: Cannot read property '0' of undefined" error. I've read a bunch of threads trying to figure out tests to detect when this happens, but none of the solutions seem to work for me.

I'm sending an http request to the following link. If you change the last 4 letters you'll get responses from different airports.
https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=2.5&mostRecentForEachStation=constraint&stationString=KBOS

I'm passing the returned message through an XML parse node, then trying to extract the temp_c data point. If that airport is reporting the value, it can be grabbed at msg.payload.response.data[0].METAR[0].temp_c[0]. However sometimes that data doesn't exist, and that's when I run into the undefined error. So I'm trying to figure out a test to determine if the temp_c data exists in the response so I can either use it, or set it to something that I can use downstream to indicate undefined. It's tricky finding an airport that always fails to report this data, at the time of writing this KOXB, KSBY, and KAQW were all returning the undefined error.

New users can't upload files, what's the easiest way to attach a slimmed down flow with just the nodes required to recreate this? I didn't want to spam a wall of JSON. Basic flow looks like this however

Edit: found the FAQ on posting flow data, so I hope I do this right.

[{"id":"83ee8e502e121006","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"6cf1ccd484f28ef4","type":"function","z":"83ee8e502e121006","name":"URL Forming","func":"\n    request = \"https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=2.5&mostRecentForEachStation=constraint&stationString=KOXB\";\n    //request += test[i];\n    //request += \"/observations/latest\";\n    node.send({topic: \"KOXB\", payload: request});\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":250,"y":120,"wires":[["f919b58fd386f142"]]},{"id":"f919b58fd386f142","type":"change","z":"83ee8e502e121006","name":"","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":410,"y":120,"wires":[["2cf594cff2ad37b1"]]},{"id":"2cf594cff2ad37b1","type":"http request","z":"83ee8e502e121006","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":570,"y":120,"wires":[["d472ecf337d7d278"]]},{"id":"2bbd8a089a6592a0","type":"inject","z":"83ee8e502e121006","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":100,"y":120,"wires":[["6cf1ccd484f28ef4"]]},{"id":"c96fe25a7b13f461","type":"function","z":"83ee8e502e121006","name":"Temp Extraction","func":"if (msg.payload.response.data[0].METAR[0].temp_c[0] != undefined){\n    test = \"true\";\n}\nelse {\n    test = \"false\";\n}\n\n//tempC = msg.payload.response.data[0].METAR[0].temp_c[0]\n//tempF = (tempC*1.8)+32;\n\n//test = typeof msg.payload.response.data[0].METAR[0].temp_c[0];\n\n//msg.payload = tempF;\nmsg.payload = test;\nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":880,"y":120,"wires":[["16c42a26fa9b5793"]]},{"id":"16c42a26fa9b5793","type":"debug","z":"83ee8e502e121006","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1050,"y":120,"wires":[]},{"id":"d472ecf337d7d278","type":"xml","z":"83ee8e502e121006","name":"","property":"payload","attr":"","chr":"","x":710,"y":120,"wires":[["c96fe25a7b13f461","fde6e0c18d48b16c"]]},{"id":"fde6e0c18d48b16c","type":"debug","z":"83ee8e502e121006","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":870,"y":160,"wires":[]}]

You could wrap your code in a try catch.

Or use optional chaining if you are using nodejs v14 or greater.

2 Likes

Somehow, in my searching I never came across the try catch approach, and that does seem to work. Thank you. Code is not my thing, so learning it takes a lot for me, appreciate the help.

I was trying all kinds of function block tests to check for undefined, or types, and none of it was working. Probably due to my own implementation problems.

edit: just in case it helps someone else, this is how I implemented it:

try{
    tempC = msg.payload.response.data[0].METAR[0].temp_c[0]
    tempF = (tempC*1.8)+32;
    node.send({topic: 1, payload: tempF});
}

catch (e){
    tempF = 4242;
    node.send({topic: 1, payload: tempF});
}

The catch sets the value to something specific that would never turn up under normal conditions, so downstream I can catch that value and know it means undefined.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.