2

I am trying to learn BackboneJS and this is the error that I am getting.

I am coding in coffeescript and this is the generated JS I have no idea why this is happening as I think that I am doing it correctly.

(function() {
  var AppRouter, MenuItemDetails, app;

  MenuItemDetails = Backbone.View.extend({
    render: function() {
      var markup;
      markup = "<div>" + this.options.category + "</div>";
      this.$el.html(markup);
      return this;
    }
  });

  AppRouter = Backbone.Router.extend({
    routes: {
      "": "list",
      "menu-items/new": "itemForm",
      "menu-items/:item": "itemDetails"
    },
    list: function() {
      return $('#app').html('List Screen');
    },
    itemDetails: function(item) {
      var view;
      view = new MenuItemDetails({
        name: item,
        category: 'Entree',
        imagepath: 'no-image.jpg'
      });
      return $('#app').html(view.render().el);
    },
    itemForm: function() {
      return $('#app').html("New item form");
    }
  });

  app = new AppRouter();

  Backbone.history.start();

}).call(this);

/*
//@ sourceMappingURL=app.map
*/

Where am I going wrong?

user3187254
  • 155
  • 2
  • 9
  • 1
    Is this similar to this question / answer? http://stackoverflow.com/questions/19325323/backbone-1-1-0-views-reading-options Basically, this.options may no longer be available by default. – Jason Reid Feb 12 '14 at 20:02
  • Thank you so much! You sent me to the right direction! – user3187254 Feb 12 '14 at 20:08

2 Answers2

1

Try to do like this :

  MenuItemDetails = Backbone.View.extend({
    initialize: function(options) {
      this.options = options;
    },
    render: function() {
      var markup;
      markup = "<div>" + this.options.category + "</div>";
      this.$el.html(markup);
      return this;
    }
  });
Rida BENHAMMANE
  • 4,111
  • 1
  • 14
  • 25
  • This is the right answer, although it could use a bit more explanation. The explanation is basically this: `options` is no longer set on `this` in the constructor, but you can still do it yourself, because it is passed to the `initialize` method as the sole argument. – Julian May 27 '23 at 16:26
-2

You're using the this keyword incorrectly.

MenuItemDetails = Backbone.View.extend({
render: function() {
  var markup;
  markup = "<div>" + this.options.category + "</div>"; // Error
  this.$el.html(markup);
  return this;
 }
});

The this is pointing to a scope that doesn't contain the property options. Yous should instead do something like this

 var self = this;
 MenuItemDetails = Backbone.View.extend({
    render: function() {
        var markup;
        markup = "<div>" + self.options.category + "</div>"; // Error
        this.$el.html(markup);
       return this;
   }
 });
Jack
  • 10,943
  • 13
  • 50
  • 65
ppoliani
  • 4,792
  • 3
  • 34
  • 62
  • I tried this : initialize: function(options) { return this.options = options || {}; }, And it worked. – user3187254 Feb 12 '14 at 20:08
  • While your point is true in plain JavaScript, that is not true when using Backbone's extend. Backbone will copy the functions you define and pass to `extend` to the object's prototype so `this` will be correctly set to an instance of the object when they are invoked. – tep Jun 02 '17 at 21:03