oshirowanen
oshirowanen

Reputation: 15925

Loop stopping when undefined

UPDATE 6:

Based on the console.log, I have noticed that some of the objects have:

thumbnail: Array[2]

Others have:

thumbnail: Object

and others don't have it at all.

So it seems that what @Felix Kling could be true.

http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%20%3D%20%22http%3A%2F%2Ffeeds.bbci.co.uk%2Fnews%2Frss.xml%22&format=json&callback=cbfunc

if you can't access the link, try:

http://pastebin.com/T4GPQvtk

UPDATE 5:

I am still getting url as undefined with:

for (var i = 0; i < news.length; i++) {
    news[i].thumbnail = ( $.isArray( news[i].thumbnail ) ) ? news[i].thumbnail : [news[i].thumbnail];

    buildHTML.push( "<a href='" + news[i].thumbnail[0].url + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );
}

UPDATE 4:

The following:

buildHTML.push( "<a href='" + news[i].thumbnail[0] ? news[i].thumbnail[0].url : $.isArray( news[i].thumbnail ) + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );

gives me:

Uncaught TypeError: Cannot read property 'url' of undefined

UPDATE 3:

The following does not seem to work either:

buildHTML.push( "<a href='" + news[i].thumbnail[0] ? news[i].thumbnail[0].url : news[i].thumbnail.url + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );

The error I get is:

Uncaught TypeError: Cannot read property 'url' of undefined

UPDATE 2:

The following does not seem to work:

buildHTML.push( "<a href='" + news[i].thumbnail=$.isArray(news[i].thumbnail)?news[i].thumbnail:[news[i].thumbnail] + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );

The error I get is:

Uncaught ReferenceError: Invalid left-hand side in assignment
$.ajax.successyql_news_widget.js:25
bjquery-1.4.2.min.js:124
c.extend.ajax.Ajquery-1.4.2.min.js:125
(anonymous function)yql:1

UPDATE 1:

The problem happens, when I add the image to push as follows:

buildHTML.push( "<img src='" + news[i].thumbnail[0].url + "' /><a href='" + news[i].link + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );

ORIGINAL QUESTION:

From the following url:

http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%20%3D%20%22http%3A%2F%2Ffeeds.bbci.co.uk%2Fnews%2Frss.xml%22&format=json&callback=cbfunc

I am trying to capture the data via a look like this:

function get_news() {
    $.ajax({
        url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%20%3D%20%22http%3A%2F%2Ffeeds.bbci.co.uk%2Fnews%2Frss.xml%22&format=json&callback=cbfunc&rand=" + Math.random(),
        type: 'GET',
        dataType: 'jsonp',
        jsonp: 'callback',
        jsonpCallback: 'cbfunc',
        error: function(xhr, status, error) {
            alert(xhr.responseText);
        },
        success: function(data) { 

            var buildHTML = [];

            var news = data.query.results.rss.channel.item;

            for (var i = 0; i < news.length; i++) {
                buildHTML.push( "<a href='" + news[i].link + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );
            }

            $('.portlet-content').empty().append(buildHTML.join("<br /><br />"))

        }

    });

}

This works fine as long as the thumbnail section looks like this:

"thumbnail": [
{
    "height": "49",
    "url": "http://news.bbcimg.co.uk/media/images/48915000/jpg/_48915868_48915872.jpg",
    "width": "66"
}
{
    "height": "81",
    "url": "http://news.bbcimg.co.uk/media/images/52468000/jpg/_52468689_48915872.jpg",
    "width": "144"
}
]

However, when the thumbnail section looks like this:

"thumbnail": {
    "height": "81",
    "url": "http://news.bbcimg.co.uk/media/images/53705000/jpg/_53705922_012314461-1.jpg",
    "width": "144"
}

I get an error "undefined", the loop stops and I get nothing on the screen.

How do I ignore those, and continue the script without it stopping on the error?

Upvotes: 0

Views: 454

Answers (4)

Felix Kling
Felix Kling

Reputation: 816580

Based on your comments, you seem to want this:

for (var i = 0; i < news.length; i++) {
    var item = news[i];

    if($.isArray(item.thumbnail)) {
        var size = +item.thumbnail[0].width * +item.thumbnail[0].height,
            selected = 0;
        for(var j = 1, jl = item.thumbnail.length; j < jl; j++) {
            var t_size = +item.thumbnail[j].width * +item.thumbnail[j].height;
            if(t_size < size) {
                size = t_size;
                selected = j;
            }
        }
        buildHMTL.push("<img src='" + news[i].thumbnail[selected].url + "' />");
    }
    buildHTML.push( "<a href='" + item.link + "' target='_blank'>" + item.title + "</a><br />" + item.pubDate );
}

Upvotes: 1

Declan Cook
Declan Cook

Reputation: 6126

You can use a Try catch or a simple IF before the code to check to see if the code is in the format you want before attempting to manipulate it. The issue seems to be that if your thumbnails 'array' is only one object its not sent as an array. A simple if check could stop this issue your having.

you can use a conditional operator which would go something like this:

buildHTML.push( "<img src='" + news[i].thumbnail[0] ? news[i].thumbnail[0].url : news[i].thumbnail.url + "' /><a href='" + news[i].link + "' target='_blank'>" + news[i].title + "</a><br />" + news[i].pubDate );

UPDATE this conditional expression will find the URL or it will just return "". I didn't see that some items have no URL which is why my first suggestion didn't work. Use this expression for getting your url

news[i].thumbnail ? news[i].thumbnail[0] ? news[i].thumbnail[0].url : news[i].thumbnail.url : ''

Upvotes: 0

Dr.Molle
Dr.Molle

Reputation: 117334

You may create an array if the json matches the 2nd example(isn't an array yet):

news[i].thumbnail=($.isArray(news[i].thumbnail))
                   ? news[i].thumbnail
                   : [news[i].thumbnail];

Upvotes: 3

setec
setec

Reputation: 16090

Add [] brackets to cast "thumbnail" from object to array.

"thumbnail": [ {
    "height": "81",
    "url": "http://news.bbcimg.co.uk/media/images/53705000/jpg/_53705922_012314461-1.jpg",
    "width": "144"
}]

will work

Upvotes: 1

Related Questions