Search code examples
javascriptextjspromisecontainersresponse

ExtJS: How to waiting for Promise response in initComponent method?


I've implemented a initComponent method to Container class and loading items config through a Promise method.

The thing during debugging firstly goes to callParent line and then executes goes to Promise method.. I've to reload the browser to be able fetching Promise response.

I've tried then() method in initComponent but gives error. How can I achieve to this usage?

- Container class with initComponent;

Ext.define('MyApp.view.Bar', {
    extend: 'Ext.container.Container',
    xtype: 'barview',
    requires: [],
    controller: 'barctrl',
    viewModel: {
        type: 'barvm'
    },

    initComponent: function () {
        let me = this;
        let fooInfo = MyApp.FooInfoClass.getFooInfo(); //There is a debugger in FooInfoClass but miss this one

        if (fooInfo) {
            if (fooInfo.self) {
                me.items = [
                    {
                        xtype: 'componentA'
                    }
                ];
            } else if (fooInfo.reference) {
                me.items = [
                    {
                        xtype: 'componentB'
                    }
                ];
            } else {
                me.items = [
                    {
                        xtype: 'componentC'
                    }
                ];
            }
        }

        debugger //Firstly comes to this one then goes to Promise 
        me.callParent(arguments);
    }
});

- Promise class and method;

Ext.define('MyApp.FooInfoClass', {
    requires: [],
    singleton: true,
    endpoint: MyApp.Url(),

    getFooInfo: function () {
        let me = this;
        let responseInfo = localStorage.getItem('foo-info');

        return JSON.parse(responseInfo);
    },

    setFooInfo: function (foo) {
        let me = this;

        me.foo = JSON.stringify(foo);
        localStorage.setItem(me.fooInfo, me.foo);
    },

    fooInfo: function () {
        let me = this;

        return new Ext.Promise(function (resolve, reject) {
            Ext.Ajax.request({
                url: me.endpoint + '/info',

                success: function(response, opts) {
                    let obj = Ext.decode(response.responseText);
                    let data = obj.data[0];
                    debugger //Secondly comes to here!
                    me.foo = data;
                    me.setFooInfo(me.foo);
                    resolve(me.foo);
                },

                failure: function(response, opts) {
                    console.log('server-side failure with status code ' + response);
                    reject(response);
                }
            });
        });
    }
});

Solution

  • You should not defer finishing the initComponent function until you have the data you need. Either you fetch the data first and instantiate the component once all your required info together (do the Ext.create() inside Promise.then()), or you let the component get its required info and add the child components at runtime based on these infos. There are only very very few things that you really have to know before calling callParent on initComponent.

    If I were you, instead of using me.items = , I would just use me.add() so that adding the child components will happen at runtime, after initialization.

    I have made a simple fiddle for you: https://fiddle.sencha.com/#view/editor&fiddle/2k9r