Looks like we can't reproduce the issue or there's a problem in the test case provided.
  1. #1
    Sencha User
    Join Date
    Aug 2011
    Posts
    13
    Vote Rating
    1
    micmac_creations is on a distinguished road

      1  

    Default Localstore proxy not removing indexes after records deleted

    Localstore proxy not removing indexes after records deleted


    Sencha Touch version tested:
    • Sencha Touch 2.0.0
    Browser versions tested against:
    • Google Chrome (21.0.1155.2 dev)
    Description:

    I am having some trouble with a Sencha Touch data store and a localproxy. Basically, when a record is removed from the store, using the store.remove(record) method, the record itself is removed from memory, but the Id reference to it in the store is not removed, so when the page is refreshed, I receive a lovely "Uncaught TypeError: Cannot read property 'isModel' of undefined"



    Steps to reproduce the problem:
    • Create a store, with a localstorage proxy
    • Add at least 2 items to the store
    • Remove one of them using store.remove(record) method
    The result that was expected:
    • The record is removed from localstorage, and the Id removed from the localstore.
    The result that occurs instead:
    • The record is removed from localstorage, but the id is not removed from the store itself, so when the page is refreshed, the store throws an undefined exception
    Test Case:

    Here is the code for the store:



    Code:
    Ext.define("App.store.Data", {
        extend: "Ext.data.Store",
        requires: "Ext.data.proxy.LocalStorage",
        config: {
            model: "App.model.Data",
            autoSync: true,
            proxy: {
                type: 'localstorage',
                id: 'app-store'
            }
        }
    });
    Here is the code for the delete button on the data editor page


    Code:
    onDeleteHomeworkCommand: function () {
    
        var dataEditor = this.getDataEditor();
        var currentData = dataEditor.getRecord();
        var dataStore = Ext.getStore("Data");
    
        dataStore.remove(currentData);
        dataStore.sync();
    
        this.activateDataList();
    },
    Screenshot:Debugging already done:
    • Manual removal of Ids from data store
    Possible fix:
    • Somehow get the data store to sync

    Additional CSS used:
    • only default

    Operating System:
    • Mac OSX 10.7.3

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    36,649
    Vote Rating
    817
    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


    The id item in localStorage gets removed for me using this test case using 2.0.0 and 2.0.1:

    Code:
    /**
     * This has been tested with ST 2.0.1
     *
     * This shows localstorage adding, removing, and loading
     */
    
    Ext.define('TestModel', {
        extend : 'Ext.data.Model',
    
        config : {
            identifier : 'uuid',
            fields     : [
                'test'
            ]
        }
    });
    
    var store = new Ext.data.Store({
        autoLoad  : true,
        model     : 'TestModel',
        proxy     : {
            type : 'localstorage',
            id   : 'test'
        },
        listeners : {
            load : function (s) {
                console.log('Data loaded, store has ' + s.getCount() + ' items');
            }
        }
    });
    
    new Ext.Container({
        fullscreen : true,
        items      : [
            {
                xtype   : 'button',
                text    : 'Add Data',
                handler : function () {
                    store.add([
                        { test : 'One'   },
                        { test : 'Two'   },
                        { test : 'Three' }
                    ]);
                    store.sync();
    
                    console.log('Data added, store has ' + store.getCount() + ' items');
                }
            },
            {
                xtype   : 'button',
                text    : 'Remove First Record',
                handler : function () {
                    var rec = store.getAt(0);
                    store.remove(rec);
                    store.sync();
    
                    console.log('First record removed, store has ' + store.getCount() + ' items');
                }
            },
            {
                xtype   : 'button',
                text    : 'Clear Data',
                handler : function () {
                    store.removeAll();
                    store.sync();
    
                    console.log('Data cleared, store has ' + store.getCount() + ' items');
                }
            },
            {
                xtype   : 'button',
                text    : 'Remove At Index',
                handler : function () {
                    Ext.Msg.prompt('Index', 'What index to remove?', function (btn, index) {
                        if (btn === 'ok') {
                            store.removeAt(index);
                            store.sync();
    
                            console.log('Record removed at index ' + index + '. Store has ' + store.getCount() + ' items')
                        }
                    });
                }
            },
            {
                xtype   : 'button',
                text    : 'Console Record Data',
                handler : function () {
                    console.log('Record data:');
    
                    store.each(function (record) {
                        console.log(record.getData());
                    });
                }
            },
            {
                xtype   : 'button',
                text    : 'Alert Number of Records',
                handler : function () {
                    alert('Data loaded, store has ' + store.getCount() + ' items');
                }
            }
        ]
    });
    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
    May 2012
    Posts
    1
    Vote Rating
    0
    BigLittleFlan is on a distinguished road

      0  

    Default I've got the exact same problem as OP

    I've got the exact same problem as OP


    Hi,

    I have the same problem as the original poster, could you elaborate on what you had to do to fix this?

    My code:

    Model:
    Code:
    Ext.define('App.model.User', {    extend: 'Ext.data.Model',
    
    
        config: {
            fields: [ 
    			{ name: 'id', type: 'int'},
    			{ name: 'fname', },
    			{ name: 'sname', },
    			{ name: 'email', },
    			{ name: 'phone', },
    			{ name: 'network', },
    			{ name: 'password', },
    			{ name: 'loggedIn' },
    			{ name: 'app_auth' },
    			{ name: 'bango_id' }
    		]
        }
    });
    Store:
    Code:
    Ext.define('App.store.LocalUser', {
        extend: 'Ext.data.Store',
    
    
        config: {
            model: 'App.model.User',
    		proxy : {
    			type : 'localstorage',
    			id : 'local-user'
    		}
        }
    });
    Controller (I've tried both looping through and deleting all entries as well as using removeAll):
    Code:
        doLogout: function() { 
            this.LocalUser = Ext.getStore('LocalUser');
            this.LocalUser.each(function(record){
                this.LocalUser.remove(record);
                this.LocalUser.sync();
            }, this);
            this.LocalUser.removeAll();
            this.LocalUser.sync();
            
           	this.showLogin();
        },
    Local storage:

    Before .sync:
    before.jpg

    After .sync:
    after.jpg

  4. #4
    Sencha User
    Join Date
    Aug 2011
    Posts
    13
    Vote Rating
    1
    micmac_creations is on a distinguished road

      0  

    Default


    What version of ST are you using? After updating to 2.0.1.1, this bug was gone, and my app worked fine, so make sure your ST version is up to date.

  5. #5
    Sencha User
    Join Date
    May 2012
    Posts
    1
    Vote Rating
    0
    grzechu is on a distinguished road

      0  

    Default


    Hi,
    I had the same issue after upgrading to ST 2.0.1.1 the problem was how model id's where generated :
    in my ST 2.0.0 app my model was defined :
    Code:
    [...]
    extend : "Ext.data.Model",
        config : {
            idProperty : "id",
            fields : [
                { name : "id", type : "int " },
    [...]
    and id where generated as int's :
    Code:
    var absoluteMaxId = myStore.max("id");
    var personId = (absoluteMaxId == null) ? 0 : (absoluteMaxId + 1);
    i had a clean id's under my controll

    in ST 2.0.1.1 had to switch model def to :
    Code:
    [...]
    extend : "Ext.data.Model",
        config : {
            idProperty : "id",
            identifier: "uuid",
            fields : [
                { name : "id", type : "auto" },                
    [...]
    i also had to remove my own way o generating id's
    Code:
    var absoluteMaxId = myStore.max("id");
    var personId = (absoluteMaxId == null) ? 0 : (absoluteMaxId + 1);
    because with my own id's ST 2.0.1.1 wouldn't remove indexes from the localstore

    Now id's are generated with uuid's and its working ok, although i don't understand why was it changed in the new release if there were no problems (at least in my case)

  6. #6
    Sencha User
    Join Date
    Nov 2012
    Posts
    1
    Vote Rating
    0
    electrichead is on a distinguished road

      0  

    Default


    I think that this issue has to be re-opened. There are many of us with the same problem and the test case that Mitchell used was not the same as the one provided by OP.

    The console.log returns the correct info, but the proxy is *not* cleared, which is visible using the web inspector of the browser. The ids of the deleted items stick around and cause an error on page refresh: Uncaught TypeError: Cannot read property 'isModel' of undefined

    I am experiencing this on 2.0.1.1


    Quote Originally Posted by mitchellsimoens View Post
    The id item in localStorage gets removed for me using this test case using 2.0.0 and 2.0.1:

    Code:
    /**
     * This has been tested with ST 2.0.1
     *
     * This shows localstorage adding, removing, and loading
     */
    
    Ext.define('TestModel', {
        extend : 'Ext.data.Model',
    
        config : {
            identifier : 'uuid',
            fields     : [
                'test'
            ]
        }
    });
    
    var store = new Ext.data.Store({
        autoLoad  : true,
        model     : 'TestModel',
        proxy     : {
            type : 'localstorage',
            id   : 'test'
        },
        listeners : {
            load : function (s) {
                console.log('Data loaded, store has ' + s.getCount() + ' items');
            }
        }
    });
    
    new Ext.Container({
        fullscreen : true,
        items      : [
            {
                xtype   : 'button',
                text    : 'Add Data',
                handler : function () {
                    store.add([
                        { test : 'One'   },
                        { test : 'Two'   },
                        { test : 'Three' }
                    ]);
                    store.sync();
    
                    console.log('Data added, store has ' + store.getCount() + ' items');
                }
            },
            {
                xtype   : 'button',
                text    : 'Remove First Record',
                handler : function () {
                    var rec = store.getAt(0);
                    store.remove(rec);
                    store.sync();
    
                    console.log('First record removed, store has ' + store.getCount() + ' items');
                }
            },
            {
                xtype   : 'button',
                text    : 'Clear Data',
                handler : function () {
                    store.removeAll();
                    store.sync();
    
                    console.log('Data cleared, store has ' + store.getCount() + ' items');
                }
            },
            {
                xtype   : 'button',
                text    : 'Remove At Index',
                handler : function () {
                    Ext.Msg.prompt('Index', 'What index to remove?', function (btn, index) {
                        if (btn === 'ok') {
                            store.removeAt(index);
                            store.sync();
    
                            console.log('Record removed at index ' + index + '. Store has ' + store.getCount() + ' items')
                        }
                    });
                }
            },
            {
                xtype   : 'button',
                text    : 'Console Record Data',
                handler : function () {
                    console.log('Record data:');
    
                    store.each(function (record) {
                        console.log(record.getData());
                    });
                }
            },
            {
                xtype   : 'button',
                text    : 'Alert Number of Records',
                handler : function () {
                    alert('Data loaded, store has ' + store.getCount() + ' items');
                }
            }
        ]
    });

  7. #7
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    36,649
    Vote Rating
    817
    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


    Give me a runnable testcase and I will test it
    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.

  8. #8
    Sencha User
    Join Date
    Jan 2012
    Posts
    14
    Vote Rating
    0
    pansiom is on a distinguished road

      0  

    Default 因为你存在旧版本的store,所以不能被识别!你可以把store全删掉以解决问题

    因为你存在旧版本的store,所以不能被识别!你可以把store全删掉以解决问题


    QQ截图20130405171725.png

  9. #9
    Sencha Premium Member
    Join Date
    Apr 2011
    Location
    Chicago, IL
    Posts
    65
    Vote Rating
    11
    ccg will become famous soon enough

      0  

    Default Cannot have an "id" field in your model

    Cannot have an "id" field in your model


    The runnable test case is easy to produce with Sencha Touch 2.0.1.1. Add an 'id' field to your model. Now, even if you have a globally unique id on each model instance, the localstorage proxy doesn't work correctly. In Mitchell's example, remove "identifier: 'uuid'" and add an 'id' field:

    Code:
    Ext.define('TestModel', {
        extend : 'Ext.data.Model',
    
    
        config : {
            fields     : [
                'id',
                'test'
            ]
        }
    });
    Then, when adding records, make sure that their id's are globally unique:

    Code:
    new Ext.Container({
        fullscreen : true,
        items      : [
            {
                xtype   : 'button',
                text    : 'Add Data',
                handler : function () {
                    store.add([
                        { id: 'mynamespace-1', test : 'One'   },  // or simply {id: 1, test: 'One'}, etc.
                        { id: 'mynamespace-2', test : 'Two'   },
                        { id: 'mynamespace-3', test : 'Three' }
                    ]);
                    store.sync();
    
    
                    console.log('Data added, store has ' + store.getCount() + ' items');
                }
            },
            ....
    Now you cannot save data into localstorage. When you reload the test page, the store is empty.

    It would seem that ST 2.0.x does not handle model id's as one would expect when using a local-storage proxy. In my case, my data records are already guaranteed to have globally unique ids that are meaningful to the app, so I do not want to use a uuid. Despite having a globally unique id on each model instance, when the user removes a record from the local-storage data store, the removed record's id remains in the list of ids in local storage, so when you reload the app, it crashes with "Uncaught TypeError: Cannot read property 'isModel' of undefined" because, apparently, it's trying to read a model instance that is no longer in storage.

  10. #10
    Sencha User
    Join Date
    Aug 2012
    Location
    Vancouver, Canada
    Posts
    29
    Vote Rating
    1
    trevorcox is on a distinguished road

      0  

    Default I'm having this problem in Sencha Touch 2.2.1

    I'm having this problem in Sencha Touch 2.2.1


    I'm not seeing the exception, but just as above the indexes are not removed from localstorage. In my case I am using uuid, but I also set idProperty which is probably where the bug arises:

    identifier: 'uuid',
    idProperty: 'sid',