javascriptxmlreturn-valueyahoo-widgets

How do I get my widget not to crash if there is no value in a xml node?


I'm getting an xml file and want to get data from it. The source of the xml doesn't really matter but what I;ve got to get a certain field is:

tracks = xmlDoc.getElementsByTagName("track");
variable = tracks.item(i).childNodes.item(4).childNodes.item(0).nodeValue;

Now this works like a charm, EXCEPT when there is no value in the node. So if the structure is like this:

<xml>
 <one>
  <two>nodeValue</two>
 </one>
 <one>
  <two></two>
 </one>
</xml>

the widget will crash on the second 'one' node, because there is no value in the 'two' node. The console says:

TypeError: tracks.item(i).childNodes.item(4).childNodes.item(0) has no properties

Any ideas on how to get the widget to just see empty as an empty string (null, empty, or ""), instead of crashing? I'm guessing something along the lines of data, getValue(), text, or something else.

using

var track= xmlDoc.getElementsByTagName('track')[0];
var info= track.getElementsByTagName('artist')[0];
var value= info.firstChild? info.firstChild.data : '';

doesn't work and returns "TypeError: track has no properties". That's from the second line where artist is called.


Solution

  • Yahoo! Widgets does not implement all basic javascript functions needed to be able to use browser-code in a widget.

    instead of using:

    tracks = xmlDoc.getElementsByTagName("track");
    variable = tracks.item(i).childNodes.item(4).childNodes.item(0).nodeValue;
    

    to get values it's better to use Xpath with a direct conversion to string. When a string is empty in Yahoo! Widgets it doesn't give any faults, but returns the 'empty'. innerText and textContent (the basic javascript way in browsers, used alongside things like getElementsByTagName) are not fully (or not at all) implemented in the Yahoo! Widgets Engine and make it run slower and quite awfully react to xmlNodes and childNodes. an easy way however to traverse an xml Document structure is using 'evaluate' to get everything you need (including lists of nodes) from the xml.

    After finding this out, my solution was to make everything a lot easier and less sensitive to faults and errors. Also I chose to put the objects in an array to make working with them easier.

                var entries = xmlDoc.evaluate("lfm/recenttracks/track");
                var length = entries.length;
                for(var i = 0; i &lt; length; i++) {
                    var entry = entries.item(i);
                    var obj = {
                        artist: entry.evaluate("string(artist)"),
                        name: entry.evaluate("string(name)"),
                        url: entry.evaluate("string(url)"),
                        image: entry.evaluate("string(image[@size='medium'])")
                        };
                    posts[i] = obj;
                }