Search code examples
extjsextjs4rally

Copied PortfolioItem/MMF and its features, but if there are 5 features it shows 6


Copied PortfolioItem/MMF and its features, but if there are 5 features it shows 6 below is the some of the code of my app. I tried most of the things, but was able to figure out whats wrong. Any suggestion on this.

        Ext.define('CustomApp', {
            extend: 'Rally.app.App',
            componentCls: 'app',
            _newObj : {},
            _newParent : null,
            childrens: [],
            childs: [],
            _all_pis: [],
            _toBeCreatedChild : [],
            _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){
                                                        self._childObj = {};
                                                        self._childObj = portfolioitem;
                                                        self._innerModelRetrieved();
                                                    }, self);   
                                                },
                                                scope: this 
                                            });     
                                        }, self);
                                    }   
                                }
                            });
                        },
                        scope: this
                    },
                }); 
            },
            // Inner Copy functions
            _innerModelRetrieved: function() {
                var that = this;
                (function(){
                    var child = that._childObj;
                    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 ) {
                that = this;
                this.model = model;           
                that._genericInnerCopy(_childObj);
            },              
            _genericInnerCopy: function(_childObj) {
                that = this;
                model = that.model;
                var record = Ext.create(model, {
                    Name: _childObj.get('Name'),
                    //Parent: _newParent.get("_ref");,
                });
                record.save({
                    callback: function(result, operation) {
                        if(operation.wasSuccessful()) {
                            console.log("Done");
                            //that._copyChild();
                        } else {
                            console.log("error");
                        }
                    }
                })
                that._all_pis.push(record);
                //console.log("all pis values", that._all_pis);
                var store = Ext.create('Rally.data.custom.Store', {
                    data: that._all_pis,
                    listeners: {
                        load: that._updateAll,
                        scope: that
                    },     
                });
                //console.log("record values", that._all_pis);
            },  
            _updateAll: function(store,data) {
                Rally.data.BulkRecordUpdater.updateRecords({
                    records: data,
                    propertiesToUpdate: {
                        Parent: _newParent.get("_ref")
                    },
                    success: function(readOnlyRecords){
                        that._createCustomStore(data);
                        //all updates finished, except for given read only records
                    },
                    scope: that
                });
            },

In the image you can see objects, those are feature objcets.

enter image description here

enter image description here


Solution

  • Try this code, it should help. As you have used promises.

            Ext.define('CustomApp', {
                extend: 'Rally.app.App',
                componentCls: 'app',
                _newObj : {},
                _newParent : {},
                final_features : [],
                childs: [],
                _type : null,
                _parents: {}, // key is objectID of old parent, value is new parent (record)
                // RALLY a place to show stuff (nice to structure beforehand)
                items: [{xtype:'container',itemId:'display_box'}],
                launch: function() {
                    this._parents = {};
                    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;
                                // RALLY: set a ui indicator that the user should wait
                                this.setLoading("Copying");
                                // RALLY:
                                // onqModelRetrieved is called asynchronously. Without a promise
                                // it'll start but the next few lines don't wait until it's done.
                                // If it works fast enough, doesn't matter, but there is a chance
                                // it'll take longer than the thing that's needed next.
                                this.onqModelRetrieved().then({
                                    scope: this,
                                    success: function(results) {
                                        var self = this;
                                        this.setLoading("Finding Children");
                                        var child_model = this.getChildTypeFor( selectedRecord.get('PortfolioItemTypeName') ); 
                                        self.final_features = [];   
                                        // RALLY: turned this upside down.  Instead of using the collection (which
                                        // needs two calls, search for the items that have that parent
                                        Ext.create('Rally.data.wsapi.Store', {
                                            model: child_model,
                                            fetch: ['Name', 'FormattedID', 'Children', 'PortfolioItemTypeName'],
                                            filters: [{property:'Parent.ObjectID',value:selectedRecord.get('ObjectID')}],
                                            autoLoad: true,
                                            listeners: {
                                                load: function(store, records) {
                                                    var promises = []; 
                                                    Ext.Array.each(records, function(portfolioitem){
                                                        // RALLY: instead of using the global _childObj, push it in
                                                        var f = function() {
                                                            self.final_features.push(portfolioitem);
                                                            return self._innerModelRetrieved(portfolioitem);
                                                        }
                                                        promises.push(f); // not run now, but in sequence at Deft
                                                    }, self);
                                                    if ( promises.length == 0 ) {
                                                        console.log("no children");
                                                        self.setLoading(false);
                                                        //self.launch();
                                                    } else {
                                                        Deft.Chain.sequence(promises).then({
                                                            scope: self,
                                                            success: function(results) {
                                                                var promises = [];
                                                                _.each(self.final_features, function(result) {
                                                                    if (result.get('Children') && result.get('Children')._type != "PortfolioItem/Feature") {
                                                                        if (result.get('Children').Count > 0) {
                                                                            var f = function() {
                                                                                var new_parent = result;
                                                                                if ( self._parents[result.get('ObjectID')] ) {
                                                                                    new_parent = self._parents[result.get('ObjectID')];
                                                                                }
                                                                                if ( result.get('PortfolioItemTypeName') == "MMF" ) {
                                                                                    //console.log("second item", result.get('PortfolioItemTypeName'));
    
                                                                                }   
                                                                                self._newParent = new_parent;
                                                                                return self._newFunction(result);
                                                                            }   
                                                                            promises.push(f);
                                                                        }
                                                                    }   
                                                                }, self);
                                                                Deft.Chain.sequence(promises).then({
                                                                    scope: self,
                                                                    success: function(results) {
                                                                        //self.final_features.push(results.get('Children'));
                                                                        var promises = [];
                                                                        _.each(self.final_features, function(result) {
                                                                            if (result.get('Children') && result.get('Children').Count > 0) {
                                                                                if (result.get('Children')._type == "PortfolioItem/Feature") {
                                                                                    //if (result.get('Children').Count > 0) {
                                                                                    var f = function() {
    
                                                                                        var new_parent = result;
                                                                                        if ( self._parents[result.get('ObjectID')] ) {
                                                                                            new_parent = self._parents[result.get('ObjectID')];
                                                                                        }
                                                                                        self._newParent = new_parent;
                                                                                        return self._newFunction(result);
                                                                                    }   
                                                                                    promises.push(f);
                                                                                }
                                                                            }
                                                                        }, self);
                                                                        Deft.Chain.sequence(promises).then({
                                                                            scope: self,
                                                                            success: function(results) {
    
                                                                                this.setLoading(false);
                                                                                console.log('done');
                                                                                this.launch();
                                                                            },
                                                                        }); 
                                                                    }
                                                                });         
                                                            },
                                                            failure: function(message) {
                                                                alert(message);
                                                            }
                                                        });
                                                    }
                                                }   
                                            }
                                        });
                                        //self.launch();
                                    }
                                });
                            },
                            scope: this
                        },
                    }); 
                },