Search code examples
javascriptextjsextjs4rally

Last record value is displayed, not all values are looped


In the code below, in _copyChild and innerModelRetrieved functions print on console 4 features one by one, but in next function onInnerModelRetrieved 4 times last feature value is printed, I am not able to figure it why its happening like that. please help me with this.

        Ext.define('CustomApp', {               
            extend: 'Rally.app.App',
            componentCls: 'app',
            _newObj : {},
            childrens: [],
            _type : null,
            launch: function() {
                Ext.create('Rally.ui.dialog.ChooserDialog', {
                    width: 450,
                    autoScroll: true,
                    height: 525,
                    title: 'Select to Copy',
                    pageSize: 100,
                    closable: false,
                    selectionButtonText: 'Copy',                  
                    artifactTypes: ['PortfolioItem/Feature','PortfolioItem/MMF','PortfolioItem/Epic', 'PortfolioItem/Program'],
                    autoShow: true,
                    storeConfig:{
                        fetch: ['Name','PortfolioItemTypeName']
                    },
                    listeners: {
                        artifactChosen: function(selectedRecord) {
                            childrens = [];
                            this._type = selectedRecord.get('PortfolioItemTypeName');
                            this._newObj = selectedRecord;
                            this.onqModelRetrieved();
                            var self = this;
                            Ext.create('Rally.data.wsapi.Store', {
                                model: 'PortfolioItem/' + selectedRecord.get('PortfolioItemTypeName'),
                                fetch: ['Name', 'FormattedID', 'Children'],
                                pageSize: 1,
                                autoLoad: true,
                                listeners: {
                                    load: function(store, records) {
                                        final_features = [];
                                        Ext.Array.each(records, function(child){
                                            var item = selectedRecord;
                                            childrens = item.getCollection('Children');
                                            childrens.load({
                                                fetch: ['FormattedID'],
                                                callback: function(records, operation, success){
                                                    Ext.Array.each(records, function(portfolioitem){
                                                        if (portfolioitem.get('PortfolioItemTypeName') == "Feature") {
                                                            self._childObj = portfolioitem;
                                                            self._copyChild();
                                                        }   
                                                    }, self);   
                                                },
                                                scope: this 
                                            });     
                                        }, self);
                                    }   
                                }
                            });
                        },
                        scope: this
                    },
                }); 
            },
            // Inner Copy functions
            _copyChild: function() {
                console.log("child value here", that._childObj);
                this.innerModelRetrieved();
            },
            innerModelRetrieved: function() {
                var that = this
                console.log("next child value here", that._childObj);
                that._type = 'PortfolioItem/' + that._childObj.get('PortfolioItemTypeName');
                Rally.data.ModelFactory.getModel({
                    type: that._type,
                    success: that.onInnerModelRetrieved,
                    scope: that
                });     
            },                      
            onInnerModelRetrieved: function(model) {
                console.log("next child value here", this._childObj);
                this.model = model;
                this.genericInnerCopy(model);
            },

Solution

  • In order to make this work you need to create a block scope and a local variable that is set to the current childObj, otherwise onInnerModelRetrieved gets only the last value of childObj since it waits for the iterations over results to complete before it kicks in.

    The function

    (function(){...})();

    immediately invoked creates that block scope and

    var child = that._childObj

    captures individual objects at each iteration.

    Finally, the child is passed via

    success: function(model)

    which invokes onInnerModelRetrieved with two parameters, model and child

    innerModelRetrieved: function() {
        var that = this;
        (function(){
             var child = that._childObj;
             console.log("in innerModelRetrieved, that._childObj.data.FormattedID:", that._childObj.data.FormattedID);
              that._type = 'PortfolioItem/' + that._childObj.get('PortfolioItemTypeName');
              Rally.data.ModelFactory.getModel({
              type: that._type,
              success: function(model){
                   that.onInnerModelRetrieved(model, child );
              },
              scope: that
              });
           })();
    },                      
    onInnerModelRetrieved: function(model, _childObj ) {
           console.log("in onInnerModelRetrieved, that._childObj.data.FormattedID:", _childObj.data.FormattedID);
           this.model = model;                
    }
    

    Here is the screenshot before the changes:

    enter image description here

    And here is the screenshot after changes:

    enter image description here