ExtJS 4 - async callback to callParent throws exception

2

I want to prepare some Json Store before processing to callParent(), then it throws an error.

However, me.callParent() works fine outside without async callback.

Ext.define('My.desktop.AppExt', {
    extend: 'Ext.ux.desktop.App',

    someStore: null,

    init: function() {
        var me = this;
        me.someStore = Ext.create('My.store.SomeStore');
        me.someStore.load({
            scope: this,
            url: 'some/json/url',
            callback: function(records, opt, success) {
                 if (success) {
                     me.callParent(); // BOOM! ERROR HERE
                 }
            }
        });
    }
});

ERROR:

Unhandled exception at line 4245, column 17 in //localhost/js/ext-all-debug.js

0x800a138f - JavaScript runtime error:

Unable to get property 'superclass' of undefined or null reference

javascript
extjs
asked on Stack Overflow May 5, 2013 by Tom • edited May 5, 2013 by Tom

3 Answers

6

callParent relies on the context to call the right method, so if you're not actually calling it "directly" from a subclass method, you'll need to invoke it manually:

Ext.define('A', {
    foo: function(){
        console.log('foo', 'a');    
    }
});

Ext.define('B', {
    extend: 'A',
    bar: function(){
        this.self.superclass.foo.call(this);    
    }
});

Ext.onReady(function(){
    var o = new B();
    o.bar();
});
answered on Stack Overflow May 5, 2013 by Evan Trimboli
2

The best solution for this purpose is to get link to parentMethod like at callParent() function, but without invoking it:

/**
 * Returns reference to the parent class method. Works as {@link Ext.Base#callParent}, but doesn't invoke the
 * method.
 * @return {Function} Parent class method.
 */
getParentMethod: function() {
    var method,
        superMethod = (method = this.getParentMethod.caller) && (method.$previous ||
            ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name]));
    return superMethod;
},  


sampleMethod: function() {
    var parentMethod = this.getParentMethod();
    var parentArguments = arguments;
    someAsyncFunc(function() {
        parentMethod.apply(this, parentArguments); // calls parent.sampleMethod(...)
    }, this);
}
answered on Stack Overflow Aug 24, 2016 by Artem Repko
0

One of the ways I know is to use extra parameter, that indicates that parent method should be called:

init: function(callParent) {
    if (callParent) {
        this.callParent();
    }
    var me = this;
    me.someStore = Ext.create('My.store.SomeStore');
    me.someStore.load({
        scope: this,
        url: 'some/json/url',
        callback: function(records, opt, success) {
             if (success) {
                 this.init(true);
             }
        }
    });
}

If you use this.self.superclass.init.call(this) it will be ok only until somebody will create child for your class. this.self.superclass points to superclass of instance's class, so it would points to My.desktop.AppExt instead of Ext.ux.desktop.App.

Updated 24.08.2016: Published smarter solution (see another answer by me).

answered on Stack Overflow Jan 28, 2016 by Artem Repko • edited Aug 24, 2016 by Artem Repko

User contributions licensed under CC BY-SA 3.0