Question

In the code below I need to render the view only after I have got valuea from a call on the Gmaps navigator. Until I have Latitude amd Longitude I can't render the view. Followinag some answers here I'm stuck with the error

Object [object global] has no method 'afterRender Thanks for any suggestion.

initialize: function() {
    $.when(this.beforeRender).then(function(){
        this.afterRender();
    });
},

beforeRender: function () {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(this.onSuccessUpdatePos, 
                                                 this.onFailUpdatePos);
    } else {navigator.geolocation.getCurrentPosition(this.onSuccessUpdatePos, 
                                                     this.onFailUpdatePos);

    }
},

afterRender: function () {
    this.render();
},

UPDATE: I did as I was told, and it seems that the sequence BeforeRender-> render-> afterRender is respected. I also added all of the initialization logic within the function Initialize(). the problem is that putting the functions in the sequence appears not to ensure the fact that the function render() is launched once acquired results.

I also tried it with

    $.when(this.beforeRender).then(that.render);

as was suggested to me but still keeps giving me errors. It seems that beforeRender isn't launched. The error that keep showing me is

Uncaught SyntaxError: Unexpected token u

I think that happen because of sessionStorage & localStorage and these are not filled before the render function is launched. is there an effective way to wait for these results to be returned?

Was it helpful?

Solution

I think you followed some tutorial, since both beforeRender and afterRender don't exist in Backbone core. But, they are often implemented by people who need events fired before and after the rendering routine.

Moreover, Backbone leaves the render function of the View class empty, so it's up to you to implement (and even call it) when you need.

As a sidenote, it's generally not good to call render() right into the initialize() function, since often you'll need to have more control on when and how to render a view after having initialized it.

That said, I would suggest:

  • Move all of the initialization logic (like your navigator checks) inside initialize();
  • call render() out of the view (right after your new ViewName() call)

If you really need (maybe for further development of your code) before and after callbacks, you can make use of Underscore (available since it's a dependency) "wrap" function. Such approach consists of:

initialize: function() 
    this.render = _.wrap(this.render, function(render) {
        this.beforeRender();
        render();                       
        this.afterRender();
    });

}, 
render: function() {},
beforeRender: function() {},
afterRender: function() {}

With this in mind, I would go with (remember to specify an onFailUpdatePos on the View class):

initialize: function() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(this.render, this.onFailUpdatePos);
    } else {
        navigator.geolocation.getCurrentPosition(this.render, this.onFailUpdatePos);
    }
}

OTHER TIPS

this is out of context inside then

Try this instead.. Save a reference of this before calling it.

initialize: function() {
    var thisView = this;
    $.when(this.beforeRender).then(function(){
        thisView.afterRender();
    });
},
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top