chiurox
chiurox

Reputation: 1619

Backbone model not having attribute after fetch

So I'm having a problem after I'm fetching a model and trying to render it to a template in this view below. I've searched around and found out that I have to do a _.bindAll etc, but still it doesn't work. Inside the first console.log, where I'm trying to get the User's name, it returns undefined. I tried putting this.render() (due to the async nature of fetch) in the success callback but it didn't work. When I inspect what console.log(data) yields, I do see the values I want, but it seems that nothing is being passed to the template.

 define([
  'jquery',
  'underscore',
  'backbone',
  'models/UserModel',
  'text!/assets/templates/dashboard.html'
  ], function($, _, Backbone, UserModel, dashboardTemplate) {

    window.DashboardView = Backbone.View.extend({

    el: $(".content"),

    initialize: function() {
      _.bindAll(this, 'render');

      this.user = new UserModel();
      this.user.fetch({
        success: console.log(this.user.get("name")),
        error: function(model, response) {
          console.log("error fetching model");
          console.log(model);
          console.log(response);
        }
      });
    },

    render: function() {

      console.log(this);
      var data = {
        user: this.user,
        _: _
      };
      console.log(data);

      var compiledTemplate = _.template(dashboardTemplate, data);
      $(this.el).html(compiledTemplate);
    }
  });

  return DashboardView;

});

Could anyone please shed some light?

Upvotes: 0

Views: 1727

Answers (2)

loganfsmyth
loganfsmyth

Reputation: 161647

Your first issue is that your console.log runs right away, not on success.

this.user.fetch({
    success: console.log(this.user.get("name")),
    // ...

means that you are calling log and then passing the return value of that as the success callback. You need to pass an anonymous function.

var view = this;
this.user.fetch({
    success: function(){
        console.log(view.user.get("name")),
        view.render();
    },
    // ...

Second of all, when you render the template, you need to pass it the model's attributes, but currently you are passing the model itself. For this you can use toJSON to convert the model to a standard object.

var data = {
    user: this.user.toJSON(),
    // ...

Upvotes: 4

ryan
ryan

Reputation: 6655

You might want to check what the value of this is inside of your success callback, I doubt that it is the View as you expect which is why you are getting an undefined. Inside your template you can call console.log for extra debugging.

The main problem I see with your code is that _.template() returns a function not static content. Therefore you should be calling $(this.el).html(compiledTemplate());.

Passing data in the compiledTemplate setting will embed the data and make your template static. You generally should only pass your template code to _.template and then call the compiled function like so with the current data: compiledTemplate(this.user.toJSON());

Upvotes: 1

Related Questions