locked
Correct return after an async promise? RRS feed

  • Question

  • Hello,

    I am trying to understand what I am doing different in my return from the Blogs example.  I have a function that pulls out a fragment of a (below).  AcquireSyndication is the same as from the blogs example only in this particular scenario I am returning after 'content' has already been pushed on the stack and bound as undefined.  Any thoughts?


    Note:  I have an RSS feed that is working perfectly elsewhere, this is just called later and not being bound correctly.

     

        function getContent(artist) {
            var bioURL = "http://www.jambase.com/Artists/" + artist.id + "/" + artist.name.replace(/\s/g, '-') + "/Bio";
            var content;
            artist.dataPromise = acquireSyndication(bioURL);
            dataPromises.push(artist.dataPromise);
    
            // Return when all asynchronous operations are complete
            WinJS.Promise.join(dataPromises).then(function () {
                artist.dataPromise.then(function (eventResponse) {
                    var contentStart = eventResponse.response.indexOf("<span class=\"desc\">") + 19;
                    var contentEnd = eventResponse.response.indexOf("</span>", contentStart);
                    content = eventResponse.response.slice(contentStart, contentEnd);
                    artist.content = content;
                    return content;
                });
            });
        }

     

    Tuesday, July 3, 2012 2:35 AM

Answers

  • You need to make getContent an async method to make this work:

    function getContentAsync(artist) {
            var bioURL = "http://www.jambase.com/Artists/" + artist.id + "/" + artist.name.replace(/\s/g, '-') + "/Bio";
            var content;
            artist.dataPromise = acquireSyndication(bioURL);
    
            return new WinJS.Promise(function _getContentAsync(complete, error) {
                // Return when all asynchronous operations are complete
                artist.dataPromise.then(function (eventResponse) {
                    var contentStart = eventResponse.response.indexOf("<span class=\"desc\">") + 19;
                    var contentEnd = eventResponse.response.indexOf("</span>", contentStart);
                    content = eventResponse.response.slice(contentStart, contentEnd);
                    artist.content = content;
                    complete(content);
                });
            });
        }

    Also, you shouldn't be joining on the dataPromise array here.  Now that getContent is async you can save up the promises this method returns and join on them where you call getContent. There result object of that join should be something like an array of "content" from all the promises.

    • Proposed as answer by Bryan Thomas Tuesday, July 3, 2012 8:07 PM
    • Marked as answer by Dino He Tuesday, July 10, 2012 1:21 AM
    Tuesday, July 3, 2012 8:07 PM

All replies

  • How are you calling getContent() ?

    Jeff Sanders (MSFT)

    Tuesday, July 3, 2012 2:59 PM
    Moderator
  •                 events.push({
                        group: dateGroups[date],
                        key: id,
                        title: artists[artistIdx].querySelector("artist > artist_name").textContent,
                        subtitle: venue.name,
                        description: venue.city + ", " + venue.state,
                        content: getContent(artist),
                        backgroundImage: artImg,
                        artist: artist,
                        venue: venue,
                        date: date,
                        url: url
                    });

    I am calling it when pushing onto the stack of my the main list bound to the items in my UI (see getItemsFromXML from the sample blog tutorial mentioned above).   At the point that it is being pushed on the stack it is undefined because it hasn't yet returned.. When it returns content is already bound to the UI and doesn't get updated when the async call returns.
    Tuesday, July 3, 2012 7:52 PM
  • You need to make getContent an async method to make this work:

    function getContentAsync(artist) {
            var bioURL = "http://www.jambase.com/Artists/" + artist.id + "/" + artist.name.replace(/\s/g, '-') + "/Bio";
            var content;
            artist.dataPromise = acquireSyndication(bioURL);
    
            return new WinJS.Promise(function _getContentAsync(complete, error) {
                // Return when all asynchronous operations are complete
                artist.dataPromise.then(function (eventResponse) {
                    var contentStart = eventResponse.response.indexOf("<span class=\"desc\">") + 19;
                    var contentEnd = eventResponse.response.indexOf("</span>", contentStart);
                    content = eventResponse.response.slice(contentStart, contentEnd);
                    artist.content = content;
                    complete(content);
                });
            });
        }

    Also, you shouldn't be joining on the dataPromise array here.  Now that getContent is async you can save up the promises this method returns and join on them where you call getContent. There result object of that join should be something like an array of "content" from all the promises.

    • Proposed as answer by Bryan Thomas Tuesday, July 3, 2012 8:07 PM
    • Marked as answer by Dino He Tuesday, July 10, 2012 1:21 AM
    Tuesday, July 3, 2012 8:07 PM