Question

I'm trying to obtain information from a JSON file download to the client through AJAX and I'm getting different results depending on the JSON format and I don't know how to fix the one with problem.

First case:

The json files looks like:

    [{"name": "nick",
    "age": 28},
    {"name": "katie",
    "age": 32}]

My AJAX .done method looks like:

    .done(
    function(data) { 
        addObjectsDB (data, "people");
    })

This method calls a second one that iterates through data and stored correctly each object into IndexedDB.

Second case: Now I have a JSON file with different format:

    [
    {
     "husband": {
      "name": "Jhon",
      "age": 23 },
     "wife": {
      "name": "Marie",
      "age": 24 }
     }
     ]

Now my .done() AJAX method iterates through data and add each person, husband or wife to an array which is then sent to the DB with the same method than the first case:

    .done(
    function(data) { 
        var people = [];
        $(data).each(function (key, value){
            people.push(value.husband);
            people.push(value.wife);                
        });
        addObjectsDB (people, "people");
    })

In this case the insertion into the database fails, if for example, instead of adding value.husband to people array I just add value to people array the insertion works, but I need each person stored separated in the DB.

The addObjectsDB method is:

    function addObjectsDB (data, collection) {
        var objectStore = db.transaction(collection, "readwrite").objectStore(collection);
        $.each (data, function (key, value) {
            var request = objectStore.add(value);
        });
    }

As I said the first case works perfectly but the second one inserts nothing and no error is showed...

I think the problem is that I don't understand javascript types adequately but I'm starting with it and I've spent a whole evening with it.

Was it helpful?

Solution

There's nothing wrong with your IDB code. Look for your answer in the code you haven't presented, particularily the AJAX response (is your JSON parsed the way you think it is?)

Be sure to attach event listeners for the error event. I'm positive that if your IDB "inserts nothing" then in fact it's not true that "no error is showed" and rather no error is seen due to callback mismanagement.

Here's a working implementation, modified from a previous answer I've given on this tag. This implementation doesn't have the uniqueness constraints you've put on your schema on purpose: it shows that your looping is fine. The entries below all look good.

enter image description here

var db_name = 'SO_22977915',
    store_name = 'people';
$.ajax({
    url: '/echo/json/',
    type: 'post',
    dataType: 'json',
    data: {
        json: JSON.stringify({
            case1: [{
                "name": "nick",
                    "age": 28
            }, {
                "name": "katie",
                    "age": 32
            }],
            case2: [{
                "husband": {
                    "name": "Jhon",
                        "age": 23
                },
                    "wife": {
                    "name": "Marie",
                        "age": 24
                }
            }]
        })
    },
    success: function (data) {
        var request,
        upgrade = false,
            doTx = function (db, entry) {
                addData(db, entry, function () {
                    getData(db);
                });
            },
            getData = function (db) {
                db.transaction([store_name], "readonly").objectStore(store_name).openCursor(IDBKeyRange.lowerBound(0)).onsuccess = function (event) {
                    var cursor = event.target.result;
                    if (null !== cursor) {
                        console.log("entry", cursor.value);
                        cursor.continue();
                    }
                };
            },
            addData = function (db, entry, finished) {
                console.log('adding', entry);
                var tx = db.transaction([store_name], "readwrite"),
                    people = [];
                tx.addEventListener('complete', function (e) {
                    finished();
                });
                $.each(entry.case1, function (key, value) {
                    tx.objectStore(store_name).add(value);
                });
                $(entry.case2).each(function (key, value){
                        people.push(value.husband);
                        people.push(value.wife);                
                });
                $.each(people, function (key, value) {
                    tx.objectStore(store_name).add(value);
                });
            };
        request = window.indexedDB.open(db_name);
        request.oncomplete = function (event) {
            if (upgrade) {
                doTx(request.result, data);
            }
        };
        request.onsuccess = function (event) {
            if (!upgrade) {
                doTx(request.result, data);
            }
        };
        request.onupgradeneeded = function (event) {
            var db = event.target.result;
            db.createObjectStore(store_name, {
                keyPath: null,
                autoIncrement: true
            });
        }
    }
});

A cursor and console.log shows all entries as being added:

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top