1
votes

I'm having an issue where after upgrading from EXTJS 4.1 to 4.2, I'm getting the error: "Uncaught TypeError: undefined is not a function" which points to the ext-all.js addListener method for Ext.utilObservable. Specifically, when the _incr_ function is called, to increment the number of listeners:

  addListener: function(ename, fn, scope, options) {
        var me = this,
            config, event,
            prevListenerCount = 0;


        if (typeof ename !== 'string') {
            options = ename;
            for (ename in options) {
                if (options.hasOwnProperty(ename)) {
                    config = options[ename];
                    if (!me.eventOptionsRe.test(ename)) {

                        me.addListener(ename, config.fn || config, config.scope || options.scope, config.fn ? config : options);
                    }
                }
            }
            if (options && options.destroyable) {
                return new ListenerRemover(me, options);
            }
        }

        else {
            ename = ename.toLowerCase();
            event = me.events[ename];
            if (event && event.isEvent) {
                prevListenerCount = event.listeners.length;
            } else {
                me.events[ename] = event = new ExtEvent(me, ename);
            }


            if (typeof fn === 'string') {
                scope = scope || me;
                fn = Ext.resolveMethod(fn, scope);
            }
            event.addListener(fn, scope, options);



            if (event.listeners.length !== prevListenerCount) {
                me.hasListeners._incr_(ename);                   // <----- right here
            }
            if (options && options.destroyable) {
                return new ListenerRemover(me, ename, fn, scope, options);
            }
        }
    },

I've attempted it replacing it with the method from EXTJS 4.1, but am finding more errors down the line. Is it possible that EXTJS isn't properly configured or is missing files?

EDIT the offending piece:

    Ext.Loader.setConfig({
enabled: true
});
Ext.Loader.setPath('Ext.ux', '/_layouts/1033/scripts/perf/extjs/ux');

Ext.require([
        'Ext.ux.grid.Printer',
    //    'Ext.grid.plugin.BufferedRenderer'
 //  'Ext.ux.grid.plugin.BufferedRenderer'
 //       'Ext.ux.exporter.Exporter'
  ]);



Ext.onReady(function () {

Ext.QuickTips.init();
var myMask = new Ext.LoadMask('CostSummaryGrid', { msg: "Loading..." });
//debugger;

Ext.define('CostSummaryGrid', {
    extend: 'Ext.data.Model',
    fields: [{
        name: 'WBSId',
        type: 'int'
    }, {
        name: 'WBSName',
        type: 'string'
    }, {
        name: 'EndDate',
        type: 'string',
        convert: function (value, record) {
            if (value == null)
                return null;
            //debugger;
            date = Ext.Date.parse(value, 'MS', true);
            UTCdate = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
            return Ext.Date.format(UTCdate, appConfig.DateFormat);
        }
    }, {
        name: 'PlannedValue',
        type: 'float'
    }, {
        name: 'EarnedValue',
        type: 'float'
    }, {
        name: 'ActualCost',
        type: 'float'
    }, {
        name: 'ScheduleVariance',
        type: 'float'
    }, {
        name: 'CostVariance',
        type: 'float'
    }, {
        name: 'CurrentBudget',
        type: 'float'
    }, {
        name: 'EstimateAtCompletion',
        type: 'float'
    }, {
        name: 'VarianceAtCompletion',
        type: 'float'
    }, {
        name: 'SPI',
        type: 'float'
    }, {
        name: 'CPI',
        type: 'float'
    }]
});


var costSummaryStore = Ext.create("Ext.data.Store", {
    model: 'CostSummaryGrid',
    autoLoad: false,
    pageSize: 100,
    proxy: {
        type: 'ajax',
        url: siteUrl + '_vti_bin/performanceportaldata.svc/GetCostSummaryGridFiltered',
        noCache: false,
        //extraParams: {wbsFilter: ''},
        sortParam: undefined,
        limitParam: undefined,
        startParam: undefined,
        pageParam: undefined,
        headers: {
            'Accept': 'application/json'
        },
        reader: {
            type: 'json',
            root: 'd'
        }
    },
    storeId: 'CostSummaryStore',
    wbsFilterable: true,
    filterable: true,
    startDateFilterable: false,
    costSetFilterable: true,
    wbsCostFilterable: true,
    listeners: {
        beforeload: function () {
            myMask.show();
        },
        load: function () {
            myMask.hide();
           // grid.addDocked({ xtype: 'exporterbutton' }, 'top');
        },
    },
    LoadIfReady: function() {
        if (this.filterableReady === true && this.costSetFilterableReady === true
                && this.wbsCostFilterableReady === true && this.wbsFilterableReady === true) {
            debugger;
            this.load();
            return true;
        }      
    }
});

var grid = Ext.create('Ext.grid.Panel', {
    store: costSummaryStore,
    autoLoad: true,
    plugins: {
          ptype: 'bufferedrenderer',
          trailingBufferZone: 50,  // Keep 20 rows rendered in the table behind scroll
          leadingBufferZone: 100   // Keep 50 rows rendered in the table ahead of scroll
    },
    features: [{
        ftype: 'fixedsummary'
    }],
    tbar: [{
        text: 'Print',
        iconCls: 'icon-print',
        handler : function(){
            Ext.ux.grid.Printer.printAutomatically = false;
            Ext.ux.grid.Printer.print(grid);
            }
    } //john wilson was here
    ],
    showSummaryRow: false,
    columns: [{
        text: 'WBS Name',
        flex: 3,
        align: 'left',
        sortable: true,
        dataIndex: 'WBSName',
        fixedSummaryType: 'count',
        fixedSummaryRenderer: function (value, metadata, record) {
            //return Ext.String.format('<em>Totals:</em>', value);
            return value;
        }
    }, {
        text: 'Planned Value',
        flex: 2.1,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'PlannedValue',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals
    }, {
        text: 'Earned Value',
        flex: 2.1,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'EarnedValue',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    }, {
        text: 'Actual Cost',
        flex: 2.1,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'ActualCost',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    }, {
        text: '<html>Schedule <br>Variance</html>',
        flex: 2,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'ScheduleVariance',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    }, {
        text: 'Cost Variance',
        flex: 2,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'CostVariance',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    }, {
        text: '<html>Budget at <br>Completion</html>',
        flex: 2.3,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'CurrentBudget',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    }, {
        text: '<html>Estimate at <br>Completion</html>',
        flex: 2.3,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'EstimateAtCompletion',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    }, {
        text: '<html>Variance at <br>Completion</html>',
        flex: 2.3,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.gridCurrencyNoDecimals,
        dataIndex: 'VarianceAtCompletion',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: PerfPortal.Format.gridCurrencyNoDecimals

    }, {
        text: 'SPI',
        flex: 1,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.renderKPI,
        dataIndex: 'SPI',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: function (val, meta, record, ri, ci, s, v) {
            if (typeof (record) === 'undefined') {
                return null;
            }
            var earnedValue = 0, planned = 0;
            for (var i = 0; i < record.fields.length; i++) {
                var fieldName = record.fields.items[i].name;
                if (fieldName.lastIndexOf("EarnedValue", 0) === 0) {
                    earnedValue = record.get(fieldName);
                }
                if (fieldName.lastIndexOf("PlannedValue", 0) === 0) {
                    planned = record.get(fieldName);
                }
            }
            var retVal = earnedValue / planned;

            if (planned === 0) { retVal = 0; }

            if (KPIStore.getById('SPI') != null) {
                return PerfPortal.Format.renderKPIDirect(retVal, meta, 'SPI');
            }
            else
                return retVal;
        }

    }, {
        text: 'CPI',
        flex: 1,
        sortable: true,
        align: 'center',
        renderer: PerfPortal.Format.renderKPI,
        dataIndex: 'CPI',
        fixedSummaryType: 'sum',
        fixedSummaryRenderer: function (val, meta, record, ri, ci, s, v) {
            if (typeof (record) === 'undefined') {
                return null;
            }
            var earnedValue = 0, actual = 0;
            for (var i = 0; i < record.fields.length; i++) {
                var fieldName = record.fields.items[i].name;
                if (fieldName.lastIndexOf("ActualCost", 0) === 0) {
                    actual = record.get(fieldName);
                }
                if (fieldName.lastIndexOf("EarnedValue", 0) === 0) {
                    earnedValue = record.get(fieldName);
                }
            }
            var retVal = earnedValue / actual;
            if (actual === 0) { retVal = 0; }
            if (KPIStore.getById('CPI') != null) {
                return PerfPortal.Format.renderKPIDirect(retVal, meta, 'CPI');
            }
            else
                return retVal;
            //return Ext.util.Format.number(record.get('EarnedValue')/record.get('PlannedValue'),'0.00');
        }

    }],
    height: 520,
    width: 1000,
    title: 'Cost Summary',
    renderTo: 'CostSummaryGrid',
    viewConfig: {
        stripeRows: true,
        loadMask: false
    }

});

var summary = Ext.create('Ext.toolbar.Toolbar', {
    dock: 'bottom',
    //height: 25,
    items: [{ xtype: 'displayfield'}]
});

var toolBar = Ext.create('Ext.toolbar.Toolbar', {
    dock: 'bottom',
    //height: 25,
    items: [{ xtype: 'tbfill'}]
});
//var exportButton = Ext.create


grid.addDocked(toolBar);
var KPIStore = Ext.getStore('KPIStore');

if (KPIStore.isLoading()) {

    KPIStore.on('load', function (store, records, options) {
        addLegend(store, toolBar, 'CPI');
        toolBar.insert('-');
        addLegend(store, toolBar, 'SPI');
    });
}
else {
    addLegend(KPIStore, toolBar, 'CPI');
    toolBar.insert('-');
    addLegend(KPIStore, toolBar, 'SPI');
}

function addLegend(store, toolBar, type) {

    var KPIdef = store.getById(type);

    var poor = '<span style="margin-right: 5px; background-color: ' + KPIdef.data.Poor_color + '; color: ' + KPIdef.data.Poor_color + ';">__</span>' + KPIdef.data.Poor_label;
    var caution = '<span style="margin-right: 5px; margin-left: 10px; background-color: ' + KPIdef.data.Caution_color + '; color: ' + KPIdef.data.Caution_color + ';">__</span>' + KPIdef.data.Caution_label;
    var good = '<span style="margin-right: 5px; margin-left: 10px; background-color: ' + KPIdef.data.Good_color + '; color: ' + KPIdef.data.Good_color + ';">__</span>' + KPIdef.data.Good_label;

    toolBar.insert({ xtype: 'tbtext',
        padding: '5, 5, 5, 5',
        text: KPIdef.data.Title + ': ' + poor + caution + good
    }
               );
}

});

1
its more likely that you have a mix of includes in your page that are not playing well together. Try starting fresh with something very simple and then add your code to it.dbrin
Post the configuration of the component causing the issue. It is almost sure the problem lies in the application space not in the library.Saki
Most likely cause is you've got some class that isn't calling the observable constructor.Evan Trimboli
Hi all, I've updated the question with the offending piece of code. If you have any additional insight, I'd love to hear it.Max

1 Answers

1
votes

With ExtJs 4.2, If a class has Events defined on it, it has to either extend Ext.util.Observable or add mixin of Ext.util.Observable. Also Observable's constructor must be called in this class's constructor like as following snippet,

Ext.define('Employee', {
        // Change 1.....
        extend: 'Ext.util.Observable',
        constructor: function(config){

            this.addEvents({
                "sayHello" : true,
                "sayGoodbye" : true
            });
            // Change 2.....
            this.callParent(arguments)
        }
    });

OR

Ext.define('Employee', {
        extend: 'Some other class',

        // Change 1
        mixins: {
            observable: 'Ext.util.Observable'
        },

        constructor: function(config){

            this.addEvents({
                "sayHello" : true,
                "sayGoodbye" : true
            });
            // Change 2.....
            this.mixins.observable.constructor.call(this);
        }
    });