0

delaying createView until u.fetchAsync returns

I need to be able to delay the createView in my Sidebar until u.fetchAsync finishes executing. Here's my code so far:

CODE
var MainView = new KONtx.Class({
ClassName: 'MainView',
channel_obj: null,
Extends: KONtx.system.SidebarView,

initView: function(){
Server.fetchChannels();
},

createView: function(){
// how do I delay this until my data is stored in KONtx.messages.channels
}



CODE
Server = function() {
function callAPI ( url, callback ) {
var u = new URL();
u.callback = callback;
u.location = url;

log( " > Server [get] :: " + u.location );

u.fetchAsync( function(u) {
log( " < Server [" + u.response);
if ( u.response == 200 ) {
KONtx.application.setNetworkRequestFailed(false);
u.callback( u.result );
}
else {
KONtx.application.setNetworkRequestFailed(true);
log('\n%%% Beta Server: bonk! %%% --- http response --->' + u.response + "\nResult:\n" + u.result);
}
} );
}

return {
'fetchChannels': function() {
callAPI('http://www.mycompany.com/main_nav_list.js', function(response){
var channel_obj = eval(response);
KONtx.messages.store("channels", channel_obj);
});
},
};
}();

by
8 Replies
  • QUOTE (krmacode @ Feb 22 2011, 02:14 PM) <{POST_SNAPBACK}>
    I need to be able to delay the createView in my Sidebar until u.fetchAsync finishes executing. Here's my code so far:

    What you're describing is blocking code execution until your request is completed, which isn't a good model. In event-driven programming, events determine the flow of the program.

    So, createView is called when the widget receives an onLoadView event from the container, and updateView is called when the widget receives an onShowView event from the container. Most developers create their controls in createView and then update those controls in their updateView handler. If the content is available in your app by the time onLoadView is fired, then you can use that data then. Most times it's not, though, so the updateView handler can be used to initiate the fetch or retrieve the results from a previous fetch that's stored in the message center.

    A pattern I often use is to subscribe to the onApplicationStartup event and do my essential fetches then and store the results in the message center. Then, in my updateView handler of each view I'll check the message center to see if the data is there and if not I'll initiate the fetch again.
    0
  • Benjamin,
    In thinking through this a bit more, if you were to fetch the external data in your updateView, you would still have to wait until that data gets back to you so you go back to the first problem again.

    Any code snippets would be helpful here.
    0
  • Exactly. So, put in a waiting indicator and update the view content items once the data is available.
    0
  • That's what I tried and it worked. I am assuming that the WaitIndicator has a timing delay associated to it because it works if I fetch the channels in my onApplicationStartup call.
    0
  • It seems that I now have a Javascript closure issue. The following is my statement to get all the channel names into buttons. It goes ahead and populates the button names just fine but does not retain the channel_counter variable in my onSelect event handler.

    How do I correct this?

    CODE
    	createView: function() {
    var channel_obj = KONtx.messages.fetch("channels");
    for(var channel_counter = 0; channel_counter < channel_obj.items.length; channel_counter++){
    var this_butt = "button"+channel_counter;

    this.controls.this_butt = new KONtx.control.TextButton({
    guid: this_butt,
    label: channel_obj.items[channel_counter].title,
    events: {
    onSelect: function(event) {
    KONtx.application.loadView('view-Sub1', { foo: KONtx.messages.fetch("channels").items[channel_counter].url });
    }
    },
    styles: {
    width: Theme.viewSpecs.SIDE_BAR.width,
    height: KONtx.utility.scale(35),
    vOffset: channel_counter*35,
    }
    }).appendTo(this);
    }

    new KONtx.control.EmptySpace({
    styles: {
    vOffset: KONtx.utility.scale(140),
    height: Theme.viewSpecs.SIDE_BAR.height - KONtx.utility.scale(105),
    },
    }).appendTo(this);
    }
    0
  • QUOTE (krmacode @ Feb 23 2011, 11:15 AM) <{POST_SNAPBACK}>
    It seems that I now have a Javascript closure issue. The following is my statement to get all the channel names into buttons. It goes ahead and populates the button names just fine but does not retain the channel_counter variable in my onSelect event handler.

    How do I correct this?

    CODE
    	createView: function() {
    var channel_obj = KONtx.messages.fetch("channels");
    for(var channel_counter = 0; channel_counter < channel_obj.items.length; channel_counter++){
    var this_butt = "button"+channel_counter;

    this.controls.this_butt = new KONtx.control.TextButton({
    guid: this_butt,
    label: channel_obj.items[channel_counter].title,
    events: {
    onSelect: function(event) {
    KONtx.application.loadView('view-Sub1', { foo: KONtx.messages.fetch("channels").items[channel_counter].url });
    }
    },
    styles: {
    width: Theme.viewSpecs.SIDE_BAR.width,
    height: KONtx.utility.scale(35),
    vOffset: channel_counter*35,
    }
    }).appendTo(this);
    }

    new KONtx.control.EmptySpace({
    styles: {
    vOffset: KONtx.utility.scale(140),
    height: Theme.viewSpecs.SIDE_BAR.height - KONtx.utility.scale(105),
    },
    }).appendTo(this);
    }

    http://developer.yahoo.net/forum/index.php...ost&p=22413
    0
  • QUOTE (krmacode @ Feb 22 2011, 07:12 PM) <{POST_SNAPBACK}>
    Benjamin,
    In thinking through this a bit more, if you were to fetch the external data in your updateView, you would still have to wait until that data gets back to you so you go back to the first problem again.

    Any code snippets would be helpful here.

    The slight wait is acceptable as long as there's something onscreen that notifies the user that something's happening. The difference is that you're not blocking anything, as opposed to your original question.
    0
  • Thank you for all your feedback.

    This is the solution I came up. This calls a function with the counter variable that I expect.

    CODE
    /**
    * @author bgeorge
    */
    var MainView = new KONtx.Class({
    ClassName: 'MainView',
    Extends: KONtx.system.SidebarView,

    createView: function() {
    var channel_obj = KONtx.messages.fetch("channels");
    for(var channel_counter = 0; channel_counter < channel_obj.items.length; channel_counter++){
    var this_butt = "button"+channel_counter;
    var channel_content = KONtx.messages.fetch("channels").items[channel_counter];
    this.controls.this_butt = new KONtx.control.TextButton({
    guid: this_butt,
    label: channel_obj.items[channel_counter].title,
    events: {
    onSelect: this._getOnSelectTextHandler(channel_content),
    },
    styles: {
    width: Theme.viewSpecs.SIDE_BAR.width,
    height: KONtx.utility.scale(35),
    vOffset: channel_counter*35,
    }
    }).appendTo(this);
    }

    new KONtx.control.EmptySpace({
    styles: {
    vOffset: KONtx.utility.scale(140),
    height: Theme.viewSpecs.SIDE_BAR.height - KONtx.utility.scale(105),
    },
    }).appendTo(this);
    },

    _getOnSelectTextHandler: function(c){
    return function(){
    KONtx.application.loadView('view-Sub1',
    {
    channel_title: c.title,
    channel_url: KONtx.messages.fetch("channels").items[0].url
    });
    };
    },
    });


    QUOTE (Benjamin Toll @ Feb 23 2011, 03:47 PM) <{POST_SNAPBACK}>
    The slight wait is acceptable as long as there's something onscreen that notifies the user that something's happening. The difference is that you're not blocking anything, as opposed to your original question.
    0

Recent Posts

in Getting Started / Beginners - Yahoo! TV Widgets