11

Basically I'm trying to override a function by extending it. I have the following base (simplified) code:

openerp.point_of_sale = function(db) {

    var Order = Backbone.Model.extend({

        exportAsJSON: function() {
            return {'bigobject'}
        }
    })
}

Then, I'm writing my own .js where I want to inherit and override exportAsJSON function and I'm not sure how to .extend it. Here is my erroneous approach:

openerp.my_module = function(db) {

    db.point_of_sale.Order = db.point_of_sale.Order.extend({

        exportAsJSON: function() {

            var order_data = this._super();
            //... add more stuff on object
            return order_data;
        }
    })
}

What would be the correct way of doing it?

I hope I'm providing enough information for an answer (I'm working on OpenERP by the way). Any help will be appreciated.

EDIT: More specifically, the error seems to be in the extension itself:

db.point_of_sale.Order = db.point_of_sale.Order.extend({

...even if I put a simple return 0; within my exportAsJSON function, the page doesn't load and I get the following error in my browser console:

"Cannot call method 'extend' of undefined" 
nicobustillos
  • 153
  • 1
  • 10

3 Answers3

2

I think you want something like SuperClass.prototype.method.call(this):

openerp.my_module = function(db) {

    db.point_of_sale.Order = db.point_of_sale.Order.extend({

        exportAsJSON: function() {

            var order_data = db.point_of_sale.Order.prototype.exportAsJSON.call(this);
            //... add more stuff on object
            return order_data;
        }
    })
}
Trevor Dixon
  • 23,216
  • 12
  • 72
  • 109
  • 1
    It might be a good answer, however are you sure that the `class` and `superclass` do not share prototype? Or do I need to learn BackBone more? Because if they do, then obviously `exportAsJSON` will override it, making a recursive infinite loop. – freakish Oct 30 '12 at 19:03
  • Thanks for the help. However, I'm afraid the error lies in my .extend definition... and not so much in the exportAsJSON() definition. Please check my EDIT in my original post. I'm working on a OpenERP framework; maybe a deeper understanding on BackBone is required as freakish suggests. – nicobustillos Oct 30 '12 at 22:50
2

This is how you would normally do that in JavaScript:

var eaj = db.point_of_sale.Order.prototype.exportAsJSON;

db.point_of_sale.Order = db.point_of_sale.Order.extend({
    exportAsJSON: function() {

        var order_data = eaj.apply( this, arguments );
        //... add more stuff on object
        return order_data;
    }
})
freakish
  • 54,167
  • 9
  • 132
  • 169
  • Thanks again. But I get a different error with this approach: "Cannot read property 'prototype' of undefined". Also, I have made an EDIT of my original post. I'll appreciate any further help. – nicobustillos Oct 30 '12 at 22:55
  • 1
    Both the errors are the same. They are telling you that `db.point_of_sale.Order` is undefined. Which means that the real error is actually happening earlier where `point_of_sale.Order` is supposed to be defined but isn't. – slebetman Oct 31 '12 at 02:48
  • I was trying to do basically the same thing as @nicobustillos and this method worked (and made sense as soon as I saw it). You were also right in the comments to the other answer saying that calling prototype would result in an infinite loop, I tried it. – LeartS Jul 23 '14 at 11:09
2

This is basically where you problem lies:

openerp.point_of_sale = function(db) {
    var Order = Backbone.Model.extend({
     ^
     |
  this is a private variable
  not a property!

Therefore you cannot access it at all. If it was defined like this:

openerp.point_of_sale = function(db) {
    openerp.point_of_sale.Order = Backbone.Model.extend({
                           ^
                           |
                     this is now a property of point_of_sale
                     (basically public variable)

then you can access it the way you're trying to:

db.point_of_sale.Order = db.point_of_sale.Order.extend({

So, the answer is you cannot do that. You need to extend or modify db.point_of_sale instead of Order.

slebetman
  • 109,858
  • 19
  • 140
  • 171
  • I see. This makes a lot of sense. So basically you suggest that I start by extending point_of_sale: `db.point_of_sale = db.point_of_sale.extend({` and that indeed won't give an error. But how do I get to override the _exportAsJSON_ function from there? – nicobustillos Oct 31 '12 at 13:13
  • There's no way to override it I'm afraid. The only thing you can do is redefine the method: `dp.point_of_sale = some_new_function`. Yes, this means duplicating almost everything in the old function but at least it's doable. – slebetman Oct 31 '12 at 18:03