1. #1
    Sencha User
    Join Date
    Nov 2012
    Location
    Netherlands
    Posts
    50
    Answers
    6
    Vote Rating
    1
    eastlander is on a distinguished road

      1  

    Default Unanswered: Problem with nested models and list

    Unanswered: Problem with nested models and list


    Hi,

    I have a strange problem with showing nested models in a list.
    I can show the models (hasMany association) in the list, no problem. But when I add a new record to the children the List handles an onStoreUpdate event instead of onStoreAdd which I was expecting. The onStoreUpdate event handler calls the doUpdateListItem method but this throws an error because the list item it's trying to update doesn't exist (yet).

    My models:
    Code:
    Ext.define('mynamespace.model.Order',
    {
        extend: 'Ext.data.Model',
        config:
            {
                fields: [
                            { name: 'OrderId', type: 'int' }
                        ],
    
    
                associations: [
                    {
                        type: 'hasMany',
                        name: 'OrderLines',
                        model: 'mynamespace.model.OrderLine',
                        associationKey: 'OrderLines'
                    }]
            }
    });
    
    
    Ext.define('mynamespace.model.OrderLine',
    {
        extend: 'Ext.data.Model',
        config: {
            fields: [
                        { name: 'Quantity', type: 'int' },
                        { name: 'TotalPrice', type: 'float' }
                    ],
    
    
            associations: [
                    {
                        type: 'hasOne',
                        name: 'Article',
                        model: 'mynamespace.model.Article',
                        associationKey: 'Article'
                    }]
        }
    });
    
    
    Ext.define('mynamespace.model.Article',
    {
        extend: 'Ext.data.Model',
        config: {
            fields: [
                { name: 'Id', type: 'int' },
                { name: 'Number', type: 'int' },
                { name: 'Name', type: 'string' },
                { name: 'Price', type: 'float' }
            ]
        }
    });
    I'm showing the orderlines in my list by calling:
    Code:
    this.down("MyList").setStore(myOrder.OrderLines());
    Then I add my new orderline like this:
    Code:
    var article = Ext.create("mynamespace.model.Article", {
        Id: values.ArticleId,
        Number: values.Number,
        Name: values.Name,
        Price: values.Price
    });
    
    
    var orderLine = Ext.create("mynamespace.model.OrderLine", {
        Quantity: values.Quantity,
        TotalPrice: values.TotalPrice
    });
    orderLine.setArticle(article);
    
    
    myModel.OrderLines().add(orderLine);
    The result is that I get an error: Uncaught TypeError: Cannot call method 'getHeader' of undefined

    Any suggestions?

    Thanks,

    Remco

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,074
    Answers
    3500
    Vote Rating
    854
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    What ST 2.x.x version are you using?
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Sencha User
    Join Date
    Nov 2012
    Location
    Netherlands
    Posts
    50
    Answers
    6
    Vote Rating
    1
    eastlander is on a distinguished road

      0  

    Default


    Version 2.1.0

  4. #4
    Sencha User
    Join Date
    Oct 2011
    Posts
    15
    Answers
    1
    Vote Rating
    1
    digitalgerm is on a distinguished road

      0  

    Default Same problem

    Same problem


    We have the same problem. 2.1.0

    - A nested model (hasMany);
    - getMyList().setStore(myStore);
    - getMyList().getStore().add({});

    Result:
    Uncaught TypeError: Cannot call method 'getHeader' of undefined

    Solutions we came up:
    Applying try{ getMyList().getStore().add({}); } catch(err){ console.log('works') };

    // This saves the record and display it on list

    Second solution:
    Create a separate store without hasMany bind it to the list send the data from one store to another;


    Backtrace: sencha-touch-debug-all.js

    Code:
    onStoreUpdate: function(store, record, newIndex, oldIndex) {        var me = this,
                scroller = me.container.getScrollable().getScroller(),
                item;
    
    
            oldIndex = (typeof oldIndex === 'undefined') ? newIndex : oldIndex;
    
    
            if (oldIndex !== newIndex) {
                // Just refreshing the list here saves a lot of code and shouldnt be much slower
                me.doRefresh();
            }
            else {
                if (newIndex >= me.topItemIndex && newIndex < me.topItemIndex + me.listItems.length) {
                    item = me.getItemAt(newIndex);
      
                    ///===============================
                    // item === undefined;
    
                    me.doUpdateListItem(item, newIndex, me.getListItemInfo());
    
    
                    // Bypassing setter because sometimes we pass the same record (different data)
                    //me.updateListItem(me.getItemAt(newIndex), newIndex, me.getListItemInfo());
                    if (me.getVariableHeights() && me.getRefreshHeightOnUpdate()) {
                        me.updatedItems.push(item);
                        me.updateItemHeights();
                        me.refreshScroller(scroller);
                    }
                }
            }
        },

  5. #5
    Sencha User
    Join Date
    Nov 2012
    Location
    Netherlands
    Posts
    50
    Answers
    6
    Vote Rating
    1
    eastlander is on a distinguished road

      0  

    Default


    Sencha already filed a bug report for it.

    I worked around it by removing the store from the list and after the update adding it to the list again.

  6. #6
    Touch Premium Member hotdp's Avatar
    Join Date
    Nov 2010
    Location
    Denmark
    Posts
    603
    Answers
    8
    Vote Rating
    14
    hotdp will become famous soon enough

      0  

    Default


    Quote Originally Posted by eastlander View Post
    Sencha already filed a bug report for it.

    I worked around it by removing the store from the list and after the update adding it to the list again.
    Thanks, it works. Hope they fix it soon.

  7. #7
    Sencha User
    Join Date
    May 2013
    Posts
    2
    Vote Rating
    0
    aalopez is on a distinguished road

      0  

    Default


    Hi. I'm having the same issue, I wanted to ask you what do you mean by "...removing the store from the list..." How do you do that in code? Thanks.

  8. #8
    Sencha User
    Join Date
    Nov 2012
    Location
    Netherlands
    Posts
    50
    Answers
    6
    Vote Rating
    1
    eastlander is on a distinguished road

      0  

    Default


    Something like this:

    Code:
    var emptyStore = Ext.create('yoursite.store.YourStore');
    list.setStore(emptyStore);
    
    originalStore.add(yournewmodel);
    
    list.setStore(originalStore);

  9. #9
    Sencha User
    Join Date
    May 2013
    Posts
    2
    Vote Rating
    0
    aalopez is on a distinguished road

      0  

    Default


    Got it! it's working. Thanks

  10. #10
    Sencha User
    Join Date
    Feb 2013
    Posts
    16
    Vote Rating
    0
    SapphireSky is on a distinguished road

      0  

    Default


    Okay, I'm having this problem too in Touch 2.2.1. This list was working just fine when it was in 2.1.1 but once I updated it started to throw this error.

    So basically, I have a store of events which has a belongsTo association with a myEvents store. It is displayed grouped by days of the week. The main store works just fine. There is the option to filter by certain attributes, where I create a new store by the same class to store the matched records. When I try to change the store I get this error message 'Uncaught TypeError: Cannot call method 'getHeader' of undefined' and nothing shows up, but if I turn grouping off then change the store, and turn grouping back on, then it will show the results but it won't be grouped.

    I've confirmed that the error is thrown at the updateHeaderMap function. Also, if I do an each on all the records in the store and console.log each one, it prints every header just fine but with an 'undefined' at the end. I don't know where that undefined is coming from. There doesn't seem to be an extra object in the store or the list but it shows up with this code.

    Code:
    this.getSchedule().getViewItems().forEach(function(rec){console.log(rec.getHeader())})
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-878", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-881", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-884", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-887", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-890", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-893", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-896", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-899", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-902", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-905", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-908", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-911", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-914", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-917", getUniqueId: function, getId: function…}
    
    
    
    
    Class {onInitializedListeners: Array[0], initialConfig: objectClass, id: "ext-component-920", getUniqueId: function, getId: function…}
    
    
    
    undefined
    I'm really stumped by this.