locked
JavaScript Metro App tutorial not working... RRS feed

  • Question

  • Hi,

    I've been going through the JavaScript metro app tutorial, and everything has been going great until the last part. On this page: http://msdn.microsoft.com/en-us/library/windows/apps/hh465037(v=VS.85).aspx it has you add a function that is supposed to trigger when the selection of the ListView has changed. The function never triggers. I have racked my brain over this and can't figure out why. Any ideas? The code for the "posts" listview, and the function are posted as follows:

     

        <div id="posts" data-win-control="WinJS.UI.ListView"
             data-win-options="{itemRenderer: template, layout: {type: WinJS.UI.ListLayout},
                                selectionMode: 'single', onselectionchanged: selectionChanged}">
        </div>
    
        function selectionChanged(e) {
            content.innerHTML = "";
            var selection = posts.winControl.selection;
    
            if (selection.length) {
                var post = postItems[selection[0].begin];
                var contentTemplate = WinJS.UI.getControl(document.getElementById("contentTemplate"));
                contentTemplate.render(post).then(function (element) {
                    content.appendChild(element);
                });
            }
        }
    



    Thursday, September 15, 2011 5:22 AM

Answers

  • Hello! 

    I stuck for quite some time on the exact same problem and finally I found a work arround. I just added

     

    posts.addEventListener("selectionchanged", selectionChanged); 

     

    above my selectionChanged(e) function in the javascript file. When I have more time I will try to investige why when I point to this function in the html file it is not working. Maybe it is a bug in the enviroment or I don't know. Here is my whole JavaScript file 

     

    (function () {
        'use strict';
        // Uncomment the following line to enable first chance exceptions.
        Debug.enableFirstChanceException(true);
    
        WinJS.Application.onmainwindowactivated = function (e) {
            if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
                // start the download
                downloadStatus.innerText = "downloading posts...";
    
                // use the WinRT to download the RSS
                var syn = new Windows.Web.Syndication.SyndicationClient();
                var url = new Windows.Foundation.Uri("http://blogs.msdn.com/b/oldnewthing/rss.aspx");
                syn.retrieveFeedAsync(url).then(processPosts, downloadError);
    
                // process the declarative controls
                WinJS.UI.processAll();
            }
    
            function downloadError() {
                downloadStatus.innerText = "error downloading posts";
            }
    
            var postItems = [];
    
            function processPosts(feed) {
                downloadStatus.innerText = "";
    
                for (var i = 0, len = feed.items.length; i < len; i++) {
                    var item = feed.items[i];
                    var post = {
                        title: item.title.text,
                        date: item.publishedDate,
                        content: item.summary.text,
                    };
                    postItems.push(post);
                }
    
                // populate the ListView control's data source
                posts.winControl.dataSource = postItems;
            }
    //Here is my magic!!! posts.addEventListener("selectionchanged", selectionChanged); function selectionChanged(e) { content.innerHTML = ""; var selection = posts.winControl.selection; if (selection.length) { var post = postItems[selection[0].begin]; var contentTemplate = WinJS.UI.getControl(document.getElementById("contentTemplate")); contentTemplate.render(post).then(function (element) { content.appendChild(element); }); } } } WinJS.Application.start(); })();

     

    My html file is the same. In order to show the content of the selected post you have to add the css at the very end of the tutorial or otherwise it is not displayed.

    Here is some refference - http://msdn.microsoft.com/en-us/library/windows/apps/br211849(v=VS.85).aspx


     



    • Edited by Stoimen Stoimenov Thursday, September 15, 2011 12:03 PM
    • Marked as answer by Izzy54545 Thursday, September 15, 2011 1:18 PM
    Thursday, September 15, 2011 12:01 PM

All replies

  • Hello! 

    I stuck for quite some time on the exact same problem and finally I found a work arround. I just added

     

    posts.addEventListener("selectionchanged", selectionChanged); 

     

    above my selectionChanged(e) function in the javascript file. When I have more time I will try to investige why when I point to this function in the html file it is not working. Maybe it is a bug in the enviroment or I don't know. Here is my whole JavaScript file 

     

    (function () {
        'use strict';
        // Uncomment the following line to enable first chance exceptions.
        Debug.enableFirstChanceException(true);
    
        WinJS.Application.onmainwindowactivated = function (e) {
            if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
                // start the download
                downloadStatus.innerText = "downloading posts...";
    
                // use the WinRT to download the RSS
                var syn = new Windows.Web.Syndication.SyndicationClient();
                var url = new Windows.Foundation.Uri("http://blogs.msdn.com/b/oldnewthing/rss.aspx");
                syn.retrieveFeedAsync(url).then(processPosts, downloadError);
    
                // process the declarative controls
                WinJS.UI.processAll();
            }
    
            function downloadError() {
                downloadStatus.innerText = "error downloading posts";
            }
    
            var postItems = [];
    
            function processPosts(feed) {
                downloadStatus.innerText = "";
    
                for (var i = 0, len = feed.items.length; i < len; i++) {
                    var item = feed.items[i];
                    var post = {
                        title: item.title.text,
                        date: item.publishedDate,
                        content: item.summary.text,
                    };
                    postItems.push(post);
                }
    
                // populate the ListView control's data source
                posts.winControl.dataSource = postItems;
            }
    //Here is my magic!!! posts.addEventListener("selectionchanged", selectionChanged); function selectionChanged(e) { content.innerHTML = ""; var selection = posts.winControl.selection; if (selection.length) { var post = postItems[selection[0].begin]; var contentTemplate = WinJS.UI.getControl(document.getElementById("contentTemplate")); contentTemplate.render(post).then(function (element) { content.appendChild(element); }); } } } WinJS.Application.start(); })();

     

    My html file is the same. In order to show the content of the selected post you have to add the css at the very end of the tutorial or otherwise it is not displayed.

    Here is some refference - http://msdn.microsoft.com/en-us/library/windows/apps/br211849(v=VS.85).aspx


     



    • Edited by Stoimen Stoimenov Thursday, September 15, 2011 12:03 PM
    • Marked as answer by Izzy54545 Thursday, September 15, 2011 1:18 PM
    Thursday, September 15, 2011 12:01 PM
  • That works great! Thank you. I thought I had to add an event listener of some sort but for whatever reason I couldn't get it working. Thanks again!
    • Proposed as answer by mvladic Saturday, September 17, 2011 8:10 PM
    • Unproposed as answer by mvladic Saturday, September 17, 2011 8:10 PM
    Thursday, September 15, 2011 1:19 PM
  • Original code doesn't work because selectionChanged is not a global function (or function defined in global namespace). Following is another way to fix a problem.

     

    Change in HTML:

     

    <div ... data-win-options="{..., onselectionchanged: rssReader.selectionChanged}">
    

     

    (notice "rssReader.selectionChanged")

     

    Change in JS:

     

    (function () {
    
        ...
    
        WinJS.Namespace.define('rssReader', {
    
            selectionChanged: selectionChanged
    
        });
    
    })();
    

    With this JS code we defined a new global namespace rssReader with selectionChanged property containing our selectionChanged function.

     

    Same solution is used in Split Navigation project template.


    • Edited by mvladic Monday, September 19, 2011 12:44 PM
    Saturday, September 17, 2011 8:23 PM
  • Gotta love it when a simple beginner's tutorial already doesn't work!

    Thanks for fixing and explaining this!

    Thursday, October 6, 2011 8:16 PM
  • @AllerAnfangIstSchwer. Indeed. One of my pet hates is examples (no matter how simple) that don't work.

    @Stoimen Stoimenov. Thanks for that. I knew it had something to do with not getting fired, but could not quite put my finger on it. I did, however, find that I needed to move 'your magic' into the processPosts function below the posts.winControl... line otherwise it was undefined and the app failed to start.

    On the CSS side of things, the width property of #content overrides the margin-right value so the right margin is not 64px. Remove the width property and you get a larger right margin. Not a biggie, but something to note if you are wondering why 64px seems so small :)

     

    • Proposed as answer by Laura_ADM Friday, February 10, 2012 4:44 AM
    Friday, October 7, 2011 3:29 PM
  • is it just me or can anyone else reproduce broken results for this tutorial?

    I've tried your guys' revisions and I still cant get it to work!!

     

    Can someone just post their entire code? I copied the above code and it

    doesn't work - at all :(

     

    Thank you so much for your help I can't believe the tutorial is broken!

    Monday, October 24, 2011 5:44 PM
  • in the js code you want to add this at the bottom of the function ...put just before the closing })(); 

     

    WinJS.Namespace.define('rssReader', {

            selectionChanged: selectionChanged

        });

    then change the list view usage to include the rssReader namespace.

    search for this: onselectionchanged: selectionChanged

    replace with this: onselectionchanged: rssReader.selectionChanged

    -Jeff


    Jeff Sanders (MSFT)
    Monday, October 24, 2011 7:49 PM
    Moderator
  • In my solution, I didn't add my "RSSReader-specific" JS to the anonymous, self-executing function that is "default.js".  Rather, I wrote an "rssreader.js" file that declares the postItems array, processPosts, selectionChanged, and downloadError functions - leaving default.js to only handle the DOMContentLoaded event (though not used in this example), define the WinJS.Application.onmainwindowactivated function, and of course start the application thru WinJS.Application.start(). 

     

    This seems to be in line with the approach Scott Dickens takes with his "sketchapp" example in Build Session 740 (which among other things, emphasizes the order of activation events and what work should be done during each).

     

    Because I took this approach, my selectionchanged event fires and selectionChanged function works as written.

     

    So my question is:  Am I doing this right?... or am I polluting the global namespace, and instead should encapsulate absolutely everything within the self-executing function in default.js?

     

     

    -Michael

     


    Thursday, October 27, 2011 10:13 PM
  • Hi Michael,

    You are fine programming this way.  The global namespace is only global to your application, so if you application is not too complicated you should not run into any issues.  Namespace scoping is very useful but there is nothing preventing you from abandoning it.  It took me a bit to get used to it, but now I use it all the time (even in jscript outside of Metro).

    Best practice is to only expose the functions you need to expose to parts of your program and UI.  This would be especially important if you are using multiple pages, fragments and js files in your project.

    -Jeff


    Jeff Sanders (MSFT)
    Friday, October 28, 2011 1:04 PM
    Moderator
  • Great!!... thanks for the reply Jeff.  Metro is a bit of a learning curve for me, but I'm really enjoying it so far!

    -M

     

    Wednesday, November 2, 2011 9:14 PM
  • Cool M!

    Glad you are enjoying it!  Keep the comments and questions coming on the forums.

    -Jeff


    Jeff Sanders (MSFT)
    Thursday, November 3, 2011 11:53 AM
    Moderator
  • awesome dude, spent 6 straight hours before got this working all thanks to your tip!!

    Tuesday, November 8, 2011 8:40 PM