2
votes

I am trying to simply load a grid panel with data from a store in my view, but I keep getting the following error:

TypeError: name is undefined
Line: if (name === from || name.substring(0, from.length) === from) {

I have experimented with how I am initializing the panel, here is what I have currently:

Ext.define('BP.view.induction.RightPage', {
extend: 'Ext.tab.Panel',
alias : 'widget.rightpage',

title: "Right Page",    

items: [
    {
        title: 'Tasks',
        html: '',
        cId: 'tasksTab',
        initComponent: function() {
            this.add( [{
                store: 'Tasks',
                xtype: 'taskgrid',
                hideHeaders: true,
                columns: [
                    {
                        text     : 'Task ID',
                        flex     : 0,
                        sortable : false,
                        hidden   : true,
                        dataIndex: 'id'
                    }, 
                    {
                        text     : 'Task',
                        flex     : 1,
                        sortable : false,
                        dataIndex: 'name'
                    },

                ]
            }]);

            this.callParent();
        } 
    },{
        title: 'Content',
        html: '',
        cId: 'contentTab'
    }
]
});

Originally I didn't have the initComponent function, instead building items immediately - but this produced the same error.

[Edit] As requested, here is the store definition:

Ext.define('BP.store.Tasks', {
extend: 'Ext.data.Store',
requires: 'BP.model.Task',
model: 'BP.model.Task',
proxy: {
    type: 'ajax',
    url : '/resources/data/tasks.php',
    reader: {
        type:'json',
        root:'tasks'
    }
},
autoLoad: true
});

The full data is unwieldy, but here is a sample (json formatted):

{"success":true,
"tasks":[
    {"id":1,"name":"Cleaning Products","content":"Lorem ipsum...","resource_type":"text","resource_url":"","category_id":1},
    {"id":2,"name":"Preservatives","content":"Lorem ipsum...","resource_type":"text","resource_url":"","category_id":1}]
}
4
Sounds like something is wrong with the store configuration when it goes to try and get the name field for one of the records. Can you post the store definition/initialization as well as the data that it loads?Stephen Tremaine
That message is usually when it can't find one of the classes you're trying to load using strings, like "Tasks", try changing that to "BP.store.Tasks", if that doesn't work, you need to debug your script and see the stack and check out what is the class it's trying to create and having problems doing soJuan Mendes

4 Answers

5
votes

initComponent goes into class definition. in your code sample you are creating a tab panel with a generic Tasks panel to whcih you are trying to set an initComponent method. If you need that initComponent method you then need to create a separate class definition for your Tasks grid. You can't inline it.

In addition, what you are doing is overnesting panels. If you add a gridpanel to a tabpanel it automatically becomes one of the Tabs. You don't need to wrap a grid into another panel.

On debugging: make sure to use a debug version of the ExtJS lib (or the dev version). Use FF or Chrome to debug (whichever you like more). If you use FF, do get firebug addon called Illuminations for Developers - it helps tremendously with layout issues and to understand containerships and nesting issues. It also lets you see records in your store after they are loaded from server.

5
votes

In addition to dbrin's answer I am pretty sure that you didn't defined a widget called taskgrid which would cause your error.

Anyway, remove the initComponent() method and the add() method. In your case you can directly assign all to items:[] (subnote 2) that would result in the same and is the proper way of doing it. The add() method get called on instances that are already created (this may cause the error, too. See subnote 1). Also spare empty html properties.

Subnotes

  1. If you ever have the need for calling a method like add within a class defintions initComponent() method you need to enshure that you called callParent(arguments); first!

  2. Code example


Ext.define('BP.view.induction.RightPage', {
extend: 'Ext.tab.Panel',
alias : 'widget.rightpage',

title: "Right Page",    

items: [
    {
        store: 'Tasks',
        title: 'Tasks',
        xtype: 'taskgrid',
        cId: 'tasksTab',
        hideHeaders: true,
        columns: [
            {
                text     : 'Task ID',
                sortable : false,
                hidden   : true,
                dataIndex: 'id'
            }, 
            {
                text     : 'Task',
                flex     : 1,
                sortable : false,
                dataIndex: 'name'
            }
        ]
    },{
        title: 'Content',
        cId: 'contentTab'
    }
]
});

Edit

A xtype is a defined alias. Currently there are four; widget, feature, layout, plugin. In case of components you use the widget type. You can define your own by using alias: 'widget.yourname' and voilá you have your own xtype. You can refer to it using xtype: 'yourname' Why the grid not renders is hard to tell. It may depend on definitions within your extension or on the container where you render it into.

1
votes

I had the same problem when using the architect to build my project. It turned out to be a syntax error in the proxy configuration. Try modifying yours to look like this. It worked for me. Rather than just a URL, specify an api, with a read parameter.

proxy: {
    type: 'ajax',
    api: {
        read: '/resources/data/tasks.php'
    },
    reader: {
        type: 'json',
        root: 'tasks'
    }
}
0
votes

I had a similar case with the exact error, i solved it by added a constructor:

constructor: function(config) {
      this.initConfig(config);
      return this;
}

In my case i needed the initComponent, so final code will be something like:

Ext.define('SomeNewField', {
 extend: 'Ext.Something',
 alias: 'widget.SomeNewField',

initComponent: function(config) {
    this.callParent(arguments);
},

constructor:function(config) {
      this.initConfig(config);
      return this;
 }