Search code examples
ionic3ionic-storage

Ionic 3 storage set and get acting weird


I have an Ionic 3 app, where I store an array of objects in SQLite.

My this.data array (explained in the lower section) looks like this:

[
    {
        guid: "xy",
        images: [
            { guid: 0, uploaded: true },
            { guid: 1, uploaded: true }
        ],
    },
    {
        guid: "xz",
        images: [
            { guid: 0, uploaded: false },
            { guid: 1, uploaded: false }
        ],
    }
]

So an object has a guid and an array of objects again. After an item is updated I want to save all the items to the storage as well as to the uploader class' variable. The uploader class has a this.data and this.key property.

Here is a snippet from the problematic part:

updateItem(value){
    // search for the index of the item in the array
    var index = this.data.findIndex((item) => {
        return item.guid == value.guid;
    });

    if(index >= 0){
        // update the item in the array with the changed one
        this.data[index] = value;

        // this works fine, prints with the updated item
        console.log(this.data);

        // it supposed to save the whole array with the changed items
        return this.storage.set(this.key, this.data).then(() => {

            // for debug I read the data again - same happens after app restart
            this.storage.get(this.key).then((data) => {
                // this logs the initial, unchanged items
                console.log(data);
            });
        });
    }

    return Promise.reject(new Error('error'));
}

First, it searches for the index of the item in the this.data array, if found, then overrides the item in the array. Then it tries to save it into the storage. For debugging purposes, I read the storage and console.log it.

After I set the "xz" object's images to uploaded = true, I call the updateItem(secondItem).

From the first console.log I see that "xy" and "xy" object's images are all uploaded: true. The storage.set called, and inside the storage.get, the initial state occurs. The "xy" object's images are uploaded: true, but the "xz" object's are false. After I restart my app, this state loads again.

If there is only one object in this.data, the updateItem works fine, for example, I set the storage with uploaded: false, then I change the attributes, and call updateItem(firstItem), it saves the uploaded state. But if there is more than one object in the array, it only saves one.

I tried to save it as JSON, and parse when I read it back, but the results are the same.


Solution

  • I ended up cloning the array, then saving the clone and then assign the clone to the original array. This solved my problem.

    updateItem(value){
        // search for the index of the item in the array
        var index = this.data.findIndex((item) => {
            return item.guid == value.guid;
        });
    
        var newData = this.data.slice();
    
        if(index >= 0){
            // update the item in the array with the changed one
            newData[index] = value;
    
            // it supposed to save the whole array with the changed items
            return this.storage.set(this.key, newData).then(() => {
                this.data = newData;
    
                // for debug I read the data again - same happens after app restart
                this.storage.get(this.key).then((data) => {
                    // this logs the initial, unchanged items
                    console.log(data);
                });
            });
        }
    
        return Promise.reject(new Error('error'));
    }