Results 1 to 8 of 8
  1.    #1  
    Okay, so I'm trying to follow the Oreilly WebOS book. I bought it a while ago, but am just now digging into it.

    There is a spot that is getting me confused. It is telling me to add certain parts as a method, but as a newbie to all of this, I'm not sure where or what that is. Here's what I've got in my feeds.jsjsjs $file$:

    Code:
    /* Feeds - the primary data model for the News app. Feeds includes the primary
    data structure for the newsfeeds, which are structured as a list of lists:
    Feeds.list entry is:
    list[x].title String Title entered by user
    list[x].url String Feed source URL in unescaped form
    list[x].type String Feed type: either rdf, rss or atom
    list[x].numUnRead Integer How many stories are still unread
    list[x].newStoryCount Integer For each update, how many new stories
    list[x].stories Array Each entry is a complete story
    list.stories entry is:
    stories[y].title String Story title or headline
    stories[y].text String Story text
    stories[y].summary String Story text, stripped of markup
    stories[y].unreadStyle String Null when Read
    stories[y].url String Story url
    Methods:
    initialize(test) - create default and test feed lists
    getDefaultList() - returns the default feed list as an array
    */
    
    var Feeds = Class.create ({
        // Default Feeds.list
        defaultList: [
            {
                title:"New York Times",
                url:"http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml",
                type:"rss",
                numUnRead:4,
                stories:[
                    {
                        title: "Obama Warns of Prospect for Trillion-Dollar Deficits",
                        text: "Barack Obama delivered a stark assessment of the economy, saying that his administration would be forced to impose tighter discipline on government.",
                        unReadStyle: "unReadStyle",
                        url: "http://www.nytimes.com/2009/01/07/world/asia/07india.html?_r=1&partner=rss&emc=rss"
                    },
                    {
                        title: "Hundreds of Coal Ash Dumps Lack Regulation",
                        text: "Most of the coal byproduct dumps across the United States are unregulated, although they contain chemicals considered as threats to human health.",
                        unReadStyle: "unReadStyle",
                        url: "http://www.nytimes.com/2009/01/06/world/asia/06iqbal.html?partner=rss&emc=rss"
                    },
                    {
                        title: "Gazprom Dispute Entangles Europe",
                        text: "Russia's gas price dispute with Ukraine escalated, disrupting deliveries to the European Union in the midst of a bitter cold spell.",
                        unReadStyle: "unReadStyle",
                        url: "http://www.nytimes.com/2009/01/07/world/europe/07gazprom.html?partner=rss&emc=rss"
                    },
                    {
                        title: "Green Inc.: Cities Target Lending to Speed Energy Projects",
                        text: "A number of municipalities across the country are getting creative and experimenting with incremental, neighborhood- or district-based lending programs that help homeowners pay the up-front capital costs for efficiency or renewable energy projects.",
                        unReadStyle: "unReadStyle",
                        url: "http://greeninc.blogs.nytimes.com/2009/01/06/cities-usecreative-targeted-lending-to-speed-energy-projects/?partner=rss&emc=rss"
                    }
                ]
            }],
            // initialize - Assign default data to the feedlist
            initialize: function() {
                this.list = this.getDefaultList();
            },
            // getDefaultList - returns the default feed list as an array
            getDefaultList: function() {
                var returnList = [];
                for (var i=0; i<this.defaultList.length; i++) {
                returnList[i] = this.defaultList[i];
            }
            return returnList;
        },
            // updateFeedRequest - function called to setup and make a feed request
        updateFeedRequest: function(currentFeed) {
            this.currentFeed = currentFeed;
            Mojo.Log.info("URL Request: ", this.currentFeed.url);
            var request = new Ajax.Request(currentFeed.url, {
                method: "get",
                evalJSON: "false",
                onSuccess: this.updateFeedSuccess.bind(this),
                onFailure: this.updateFeedFailure.bind(this)
            });
        },
    
        // updateFeedFailure - Callback routine from a failed AJAX feed request;
        // post a simple failure error message with the http status code.
        updateFeedFailure: function(transport) {
            // Prototype template to generate a string from the return status.xs
            var t = new Template("Status #{status} returned from newsfeed request.");
            var m = t.evaluate(transport);
            // Post error alert and log error
            Mojo.Log.info("Invalid feed - http failure, check feed: ", m);
        },
        
        // updateFeedSuccess - Successful AJAX feed request (feedRequest);
        // uses this.feedIndex and this.list
        updateFeedSuccess: function(transport) {
            var t = new Template({key: "newsfeed.status", value: "Status #{status} returned from newsfeed request."});
            Mojo.Log.info("Feed Request Success: ", t.evaluate(transport));
            // Work around due to occasional XML errors
            if (transport.responseXML === null && transport.responseText !== null) {
                Mojo.Log.info("Request not in XML format - manually converting");
                transport.responseXML = new DOMParser().parseFromString(transport.responseText, "text/xml");
            }
            // Process the feed, passing in transport holding the updated feed data
            var feedError = this.processFeed(transport, this.feedIndex);
            // If successful processFeed returns News.errorNone,
            if (feedError !== News.errorNone) {
                // There was a feed process error; unlikely, but could happen if the
                // feed was changed by the feed service. Log the error.
                if (feedError == News.invalidFeedError) {
                    Mojo.Log.info("Feed ", this.nameModel.value, " is not a supported feed type.");
                }
            }
            News.feedListChanged = true;
            // If NOT the last feed then update the feedsource and request next feed
            this.feedIndex++;
            if(this.feedIndex < this.list.length) {
                this.currentFeed = this.list[this.feedIndex];
                this.updateFeedRequest(this.currentFeed);
            } else {
                // Otherwise, this update is done. Reset index to 0 for next update
                this.feedIndex = 0;
                News.feedListUpdateInProgress = false;
            }
        }
        
    });
    All of the stuff from //Update feed request to the end, with the exception of the last }); is what it told me to add as a method. I'm quite confused. Adding this stuff in made everything go blank when I try it on the emulator. I'm also confused as to how currentFeed is getting set, what it is, etc.

    Any tips or advice?

    Thanks in advance!

    Pre WiFi Tether Results
  2. #2  
    When I get a white screen, well over 90% of the time it's mismatched brackets, braces, parens, etc. I did a quick review and are you sure about the commas at the end of the end of the updatefeed functions - }, <--- might need to be }; or just }
  3.    #3  
    Okay, I've narrowed down what is giving me an error.

    Any reference to either this.currentFeed.url or currentFeed.url is throwing the following error in the palm-log tool:
    Code:
    [20091211-10:10:51.905415] error: Error: Cannot read property 'url' of undefined
    , line undefined, file undefined
    I'm absolutely stumped. In addition, I'm including the new feeds.jsjsjs $I$'$ve$ $done$ $up$. $The$ $one$ $in$ $the$ $post$ $up$ $above$ $is$ $incorrect$.

    Code:
    /* Feeds - the primary data model for the News app. Feeds include the primary
       data structure for the newsfeeds, which are structured as a list of lists:
       
       Feeds.list entry is:
        list[x].title           String  Title entered by user
        list[x].url             String  Feed source URL in unescaped form
        list[x].type            String  Feed type: either rdf, rss or atom
        list[x].numUnRead       Integer How many stories are still unread
        list[x].newStoryCount   Integer For each update, how many new stories
        list[x].stories         Array   Each entry is a complete story
        
       list.stories entry is:
        stories[y].title        String  Story title or headline
        stories[y].text         String  Story text
        stories[y].summary      String  Story text, stripped of markup
        stories[y].unreadStyle  String  Null when Read
        stories[y].url          String  Story URL
        
       Methods:
       initialize(test) - create default and test feed lists
       getDefaultList() - returns the default feed list as an array
    */
    
    var Feeds = Class.create ({
        // Default Feeds.list
        defaultList: [
                {
                    title: "Huffington Post",
                    url: "http://feeds.huffingtonpost.com/huffingtonpost/raw_feed",
                    type: "atom",
                    value:false,
                    numUnRead:0,
                    newStoryCount:0,
                    stories:[]
                },{
                    title:"Google",
                    url:"http://news.google.com/?output=atom",
                    type:"atom", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"BBC News",
                    url:"http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"New York Times",
                    url:"http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"MSNBC",
                    url:"http://rss.msnbc.msn.com/id/3032091/device/rss/rss.xml",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"National Public Radio",
                    url:"http://www.npr.org/rss/rss.php?id=1004",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"Slashdot",
                    url:"http://rss.slashdot.org/Slashdot/slashdot",
                    type:"rdf", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"Engadget",
                    url:"http://www.engadget.com/rss.xml",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"The Daily Dish",
                    url:"http://feeds.feedburner.com/andrewsullivan/rApM?format=xml",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"Guardian UK",
                    url:"http://feeds.guardian.co.uk/theguardian/rss",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"Yahoo Sports",
                    url:"http://sports.yahoo.com/top/rss.xml",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"ESPN",
                    url:"http://sports-ak.espn.go.com/espn/rss/news",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"Ars Technica",
                    url:"http://feeds.arstechnica.com/arstechnica/index?format=xml",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                },{
                    title:"Nick Carr", 
                    url:"http://feeds.feedburner.com/roughtype/unGc",
                    type:"rss", value:false, numUnRead:0, newStoryCount:0, stories:[]
                }
            ],
        
        // initialize - assign default data to the feedlist
        initialize: function() {
            this.list = this.getDefaultList();
        },
        
        // getDefaultList - returns the default feed list as an array
        getDefaultList: function() {
            var returnList = [];
            for (var i=0; i<this.defaultList.length; i++) {
                returnList[i] = this.defaultList[i];
            }
            
            return returnList;
        },
        
        // updateFeedList(index) - called to cycle through feeds. This is called
        // once per update cycle.
        updateFeedList: function(index) {
            Mojo.Log.info("Feed Update Start");
            News.feedListUpdateInProgress = true;
            
            // request fresh copies of all stories
            this.currentFeed = this.list[this.feedIndex];
            this.updateFeedRequest(this.currentFeed);
        },
        
        // updateFeedRequest - function called to setup and make a feed request
        updateFeedRequest: function(currentFeed) {
            this.currentFeed = currentFeed;
            Mojo.Log.info("URL Request: ", this.currentFeed.url);
            var request = new Ajax.Request(currentFeed.url, {
                method: "get",
                evalJSON: "false",
                onSuccess: this.updateFeedSuccess.bind(this),
                onFailure: this.updateFeedFailure.bind(this)
            });
        }, 
        
        // updateFeedFailure - Callback routine from a failed AJAX feed request;
        // Post a simple failure error message with HTTP status coe
        updateFeedFailure: function(transport) {
            // Prototype template to generate a string from the return status.xs
            var t = new Template("Status #{status} returned from newsfeed request.");
            var m = t.evaluate(transport);
            // Post error alert and log error
            Mojo.Log.info("Invalid feed - http failure, check feed: ", m);
        },
        
        // updateFeedSuccess - Successful AJAX feed request (feedRequest);
        // uses this.feedIndex and this.list
        updateFeedSuccess: function(transport) {
            var t = new Template({key: "newsfeed.status", value: "Status #{status} returned from newsfeed request."});
            Mojo.Log.info("Feed Request success: ", t.evaluate(transport));
            
            // Work around due to occasional XML errors
            if (transport.responseXML === null && transport.responseText !== null) {
                Mojo.Log.info("Request not in XML format - manually converting");
                
                transport.responseXML = new DOMParser().parseFromString(transport.resonseText, "text/xml");
            }
            
            // Process the feed, passing in transport holding the updated feed data
            var feedError = this.processFeed(transport, this.feedIndex);
            
            // If sucessful processFeed returns News.errorNone,
            if (feedError !== News.errorNone) {
                // There was a feed process error; unlikely but could happen if the
                // feed was changed by the feed service. Log the error.
                if (feedError == News.invalidFeedError) {
                    Mojo.Log.info("Feed ", this.nameModel.value, " is not a supported feed type.");
                }
            }
            
            News.feedListChanged = true;
            
            // If NOT the last feed, then update the feedsource and request next feed
            this.feedIndex++;
            if (this.feedIndex < this.list.length) {
                this.currentFeed = this.list[this.feedIndex];
                this.updateFeedRequest(this.currentFeed);
            } else {
                // Otherwise, this update is done. reset index to 0 for next update
                this.feedIndex = 0;
                News.feedListUpdateInProgress = false;
            }
        }
    });
    Last edited by Malefickus; 12/11/2009 at 11:23 AM.

    Pre WiFi Tether Results
  4. #4  
    Sorry - I didn't look closely at all your code, but your error is coming from it trying to reada feed from currentFeed and currentFeed either does not contain any values or you're going beyond the limits of the array. Speaking of which. If currentFeed holds an array you'll have to access each specifc row by this.currentFeed[0].url for row 1, ...feed[1] for row 2.

    Wish I could help more but trying to wrap up another app before the early access program closes up.
    WOG Dev - WebOS Group http://www.WebOSGroup.com
    PMP Dev - http://www.PimpMyPre.com
    Apps: WOG O.S.K., WOG Card Keeper, WOG Glowstick, WOG Kid Protect, PreLoad, PimpMySounds
  5.    #5  
    That makes sense, but then again, based on my understanding of the way the code is being processed, it is initializing with this.list = this.getDefaultList which has the feed index in it, then this.currentFeed is set to this.list[this.feedIndex] which would fix that, right?

    I don't know, I don't claim to be a pro. I'm just stuck on this, and it's sad that even when I literally copy/paste from that PDF (and fix the new lines) it still doesn't work.

    Pre WiFi Tether Results
  6. #6  
    The example app in the webOS book is basically the NewsReader app in the sdk samples directory. I ran the app in the emulator without problem. You may want to take a look at developer.palm. com. I noticed there is some good information, at least, I am finding it helpful.

    Brian
  7. #7  
    Hi,
    I am trying to understand the SDK and tried implementing the first example of news feed from Orielly Book.
    I am unable to initialize the feeds model in the stage assistant

    this.feeds = new Feeds(); does'nt seem to work. I have included the source:app/models/feeds.jsjsjs $in$ $the$ $sources$.$json$ $file$. $Still$ $it$ $does$'$nt$ $seem$ $to$ $work$.
    I am guessing it has something to do with the Class.create function in the feeds.jsjsjs . $Do$ $I$ $have$ $to$ $include$ $the$ $prototype$.$js$ $somewhere$ $in$ $the$ $project$ $so$ $that$ $the$ $class$.$create$ $works$ $or$ $does$ $it$ $comes$ $included$ $in$ $mojo$.
    Can somebody guide me through this, how to include prototype.jsjsjs $in$ $eclipse$ $so$ $that$ $the$ $class$.$create$() $works$ .
    Thanks in advance
  8. #8  
    I know this is a old thread but I was having a similar problem. But was able to solve it.
    The fix for this lies in this line of code
    var feedError = this.processFeed(transport,this.feedIndex);

    the function processFeed has to be included in the feeds.jsjsjs $which$ $unfortunately$ $is$ $not$ $mentioned$ $in$ $the$ $example$. $I$ $have$ $copied$ $this$ $function$ $from$ $the$ $sdk$ $sample$ $programs$. $It$ $solved$ $the$ $problem$.
    I am pasting the code here.

    processFeed: function(transport, index) {
    // Used to hold feed list as it's processed from the Ajax request
    var listItems = [];
    // Variable to hold feed type tags
    var feedType = transport.responseXML.getElementsByTagName("rss");

    if (index === undefined) {
    // Default index is at end of the list
    index = this.list.length-1;
    }

    // Determine whether RSS 2, RDF (RSS 1) or ATOM feed
    if (feedType.length > 0) {
    this.list[index].type = "rss";
    }
    else {
    feedType = transport.responseXML.getElementsByTagName("RDF");
    if (feedType.length > 0) {
    this.list[index].type = "RDF";
    }
    else {
    feedType = transport.responseXML.getElementsByTagName("feed");
    if (feedType.length > 0) {
    this.list[index].type = "atom";
    }
    else {

    // If none of those then it can't be processed, set an error code
    // in the result, log the error and return
    Mojo.Log.warn("Unsupported feed format in feed ",
    this.list[index].url);
    return News.invalidFeedError;
    }
    }
    }

    // Process feeds; retain title, text content and url
    switch(this.list[index].type) {
    case "atom":
    // Temp object to hold incoming XML object
    var atomEntries = transport.responseXML.getElementsByTagName("entry");
    for (var i=0; i<atomEntries.length; i++) {
    listItems[i] = {
    title: unescape(atomEntries[i].getElementsByTagName("title").item(0).textContent),
    text: atomEntries[i].getElementsByTagName("content").item(0).textContent,
    unreadStyle: News.unreadStory,
    url: atomEntries[i].getElementsByTagName("link").item(0).getAttribute("href")
    };

    // Strip HTML from text for summary and shorten to 100 characters
    listItems[i].summary = listItems[i].text.replace(/(<([^>]+)>)/ig,"");
    listItems[i].summary = listItems[i].summary.replace(/http:\S+/ig,"");
    listItems[i].summary = listItems[i].summary.replace(/#[a-z]+/ig,"{");
    listItems[i].summary = listItems[i].summary.replace(/(\{([^\}]+)\})/ig,"");
    listItems[i].summary = listItems[i].summary.replace(/digg_url .../,"");
    listItems[i].summary = unescape(listItems[i].summary);
    listItems[i].summary = listItems[i].summary.substring(0,101);
    }
    break;

    case "rss":
    // Temp object to hold incoming XML object
    var rssItems = transport.responseXML.getElementsByTagName("item");
    for (i=0; i<rssItems.length; i++) {

    listItems[i] = {
    title: unescape(rssItems[i].getElementsByTagName("title").item(0).textContent),
    text: rssItems[i].getElementsByTagName("description").item(0).textContent,
    unreadStyle: News.unreadStory,
    url: rssItems[i].getElementsByTagName("link").item(0).textContent
    };

    // Strip HTML from text for summary and shorten to 100 characters
    listItems[i].summary = listItems[i].text.replace(/(<([^>]+)>)/ig,"");
    listItems[i].summary = listItems[i].summary.replace(/http:\S+/ig,"");
    listItems[i].summary = listItems[i].summary.replace(/#[a-z]+/ig,"{");
    listItems[i].summary = listItems[i].summary.replace(/(\{([^\}]+)\})/ig,"");
    listItems[i].summary = listItems[i].summary.replace(/digg_url .../,"");
    listItems[i].summary = unescape(listItems[i].summary);
    listItems[i].summary = listItems[i].summary.substring(0,101);
    }
    break;

    case "RDF":
    // Temp object to hold incoming XML object
    var rdfItems = transport.responseXML.getElementsByTagName("item");
    for (i=0; i<rdfItems.length; i++) {

    listItems[i] = {
    title: unescape(rdfItems[i].getElementsByTagName("title").item(0).textContent),
    text: rdfItems[i].getElementsByTagName("description").item(0).textContent,
    unreadStyle: News.unreadStory,
    url: rdfItems[i].getElementsByTagName("link").item(0).textContent
    };

    // Strip HTML from text for summary and shorten to 100 characters
    listItems[i].summary = listItems[i].text.replace(/(<([^>]+)>)/ig,"");
    listItems[i].summary = listItems[i].summary.replace(/http:\S+/ig,"");
    listItems[i].summary = listItems[i].summary.replace(/#[a-z]+/ig,"{");
    listItems[i].summary = listItems[i].summary.replace(/(\{([^\}]+)\})/ig,"");
    listItems[i].summary = listItems[i].summary.replace(/digg_url .../,"");
    listItems[i].summary = unescape(listItems[i].summary);
    listItems[i].summary = listItems[i].summary.substring(0,101);
    }
    break;
    }

    // Update read items by comparing new stories with stories last
    // in the feed. For all old stories, use the old unreadStyle value,
    // otherwise set unreadStyle to News.unreadStory.
    // Count number of unread stories and store value.
    // Determine if any new stories when URLs don't match a previously
    // downloaded story.
    //
    var numUnRead = 0;
    var newStoryCount = 0;
    var newStory = true;
    for (i = 0; i < listItems.length; i++) {
    var unreadStyle = News.unreadStory;
    var j;
    for (j=0; j<this.list[index].stories.length; j++ ) {
    if(listItems[i].url == this.list[index].stories[j].url) {
    unreadStyle = this.list[index].stories[j].unreadStyle;
    newStory = false;
    }
    }

    if(unreadStyle == News.unreadStory) {
    numUnRead++;
    }

    if (newStory) {
    newStoryCount++;
    }

    listItems[i].unreadStyle = unreadStyle;
    }

    // Save updated feed in global feedlist
    this.list[index].stories = listItems;
    this.list[index].numUnRead = numUnRead;
    this.list[index].newStoryCount = newStoryCount;

    // If new feed, the user may not have entered a name; if so, set the name to the feed title
    if (this.list[index].title === "") {
    // Will return multiple hits, but the first is the feed name
    var titleNodes = transport.responseXML.getElementsByTagName("title");
    this.list[index].title = titleNodes[0].textContent;
    }
    return News.errorNone;
    },


    Quote Originally Posted by Malefickus View Post
    That makes sense, but then again, based on my understanding of the way the code is being processed, it is initializing with this.list = this.getDefaultList which has the feed index in it, then this.currentFeed is set to this.list[this.feedIndex] which would fix that, right?

    I don't know, I don't claim to be a pro. I'm just stuck on this, and it's sad that even when I literally copy/paste from that PDF (and fix the new lines) it still doesn't work.

Posting Permissions