4

I've a model listen on the vent for a event update:TotalCost, which is triggered from (unrelated) Collection C when any model M belonging to collection C changes.

This event is coded in the initialize method as below. On receiving the event I get the following error:

TypeError: this.set is not a function
this.set({ "totalsale": value});

CostModel = Backbone.Model.extend({     
  defaults: {
    totalSale: 0,
    totalTax: 0
  },

  initialize: function(attrs, options) {
    if(options) {
      if(options.vent) {
        this.vent = options.vent;
      }
    }
            
    this.vent.on("update:TotalCost", function(value) {
      this.set({ "totalSale": value}); **//ERROR HERE**
    });
  }
});
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Nilesh Kale
  • 233
  • 1
  • 4
  • 12

7 Answers7

12

It is highly possible you've forgot to add the new keyword before your model for example you have:

var user = UserModel();

// instead of 

var user = new UserModel();
ismnoiet
  • 4,129
  • 24
  • 30
3

Perhaps you want this to refer to current CostModel instance, to do so you need to pass this to this.vent.on call so event callback will be executed in context of model:

this.vent.on("update:TotalCost", function(value) {
    this.set({ "totalSale": value});
}, this);
Andrey Kuzmin
  • 4,479
  • 2
  • 23
  • 28
  • I tried adding 'this' as the 3rd. But still getting same error. Do I need to use any _.bind calls for this to work? My knowledge about using bind is very sketchy. – Nilesh Kale May 03 '13 at 12:31
  • Have you tried to set breakpoint in the event body and check what is `this`? – Andrey Kuzmin May 03 '13 at 12:51
  • Yes, I just checked in firebug, 'this' is actually the window object! I so surely assumed that 'this' would be the model instance! Any clues on why reference to 'this' is now Window – Nilesh Kale May 03 '13 at 15:42
  • What is `this.vent`? In either way if its backbone view, model or collection, `this` is supposed to refer to that instance, not window. – Andrey Kuzmin May 03 '13 at 16:54
  • vent is event aggregation provided by Marionette backbone plugin. see: https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.application.md#appvent-event-aggregator – Nilesh Kale May 03 '13 at 20:12
  • I see it [uses Backbone.Events mixin](https://github.com/marionettejs/backbone.wreqr/blob/master/src/wreqr.eventaggregator.js), so `vent.on` should accept context as the 3rd argument. Got no clue why its not working. – Andrey Kuzmin May 03 '13 at 20:46
3

Have you tried using a closure?

CostModel = Backbone.Model.extend({     
  defaults: {
    totalSale: 0,
    totalTax: 0
  },
  initialize: function(attrs, options) {
    var self = this;

    if(options) {
      if(options.vent) {
        this.vent = options.vent;
      }
    }

    this.vent.on("update:TotalCost", function(value) {
      self.set({ "totalSale": value}); 
    });
  }
});
Scott Puleo
  • 3,684
  • 24
  • 23
  • Thanks - this works! I just checked in firebug before using closure above, 'this' is actually the window object! I so surely assumed that 'this' would be the model instance! Any clues on why reference to 'this' is now Window – Nilesh Kale May 03 '13 at 16:12
  • Hard to say without seeing how you instantiate the model. If you share your code I will fiddle it and try and see what is happening. – Scott Puleo May 03 '13 at 18:46
  • Thanks for offering to help out, alas, easier said then done as lots of other dependent components and layout/regions for me to make a clean cut of workable code for fiddle! :( – Nilesh Kale May 03 '13 at 20:14
1

it may be due to 'set' works on model not on object. so you can, first convert your object in to model then try..

in example:

new Backbone.Model(your_object).set('val', var);
goto
  • 7,908
  • 10
  • 48
  • 58
raman rai
  • 9
  • 1
0

Another cause of this error can be if you try to create a new model without using the "new" keyword

Brian
  • 1,026
  • 1
  • 15
  • 25
0

I was getting this mysterious error when using it with Parse. I had:

Parse.User().current().escape("facebookID")

... when I should have had:

Parse.User.current().escape("facebookID")

Removed the extra () and it works fine now.

Jeremy Knight
  • 604
  • 7
  • 10
0

Another cause:

// render() method in view object
setInterval(this.model.showName, 3000);

// showName() method in model object
showName: function(){
    console.log(this.get('name')); // this.get is not a function
}
manix
  • 14,537
  • 11
  • 70
  • 107