JSON problems

So, I got an observable. I stringify it like so:

JSON.stringify();

Then I save it to a file. Cause I have trouble reading from that file back, I just took the json code out of the file and added it to a variable like so:

var json = " json code generated from the JSON.stringifiy before ";

After I try to parse it back with

JSON.parse();

and put the result to an observable. I have tried everything. =, for i loop and setting up. It just doesn’t work. How can I do that?

Just if anyone asks, I am using the todo app and I am making it actually remember the todos. Just for training.

Hi, can you please post the actual code you are using instead of just pseudo code? The problem is probably somewhere in the details, so I can’t spot it without seeing the actual code. Thanks

Here you are!

var Observable = require("FuseJS/Observable");
var Storage = require("FuseJS/Storage");

function Task(title){
    var self = this;
    this.title = title;
    this.checked = Observable(false);
    this.hidden = Observable(function(){
        if (currentTab.value == "all"){
            return false;
        }
        else if (currentTab.value == "active"){
            return self.checked.value ? true : false;
        }
        else {
            return self.checked.value ? false : true;
        }
    });
}

function Push() {
    var string = "";
    Storage.write("todoListJSON", JSON.stringify(todoList));
}

var json = '{"_subscribers":[null],"_isLeaf":true,"_values":[{"title":"Test","checked":{"_subscribers":[null],"_isLeaf":true,"_values":[true]},"hidden":{"_subscribers":[null],"_values":[false],"_dependencies":[{"_subscribers":[null,null,null],"_isLeaf":true,"_values":["all"]}]}},{"title":"Test1","checked":{"_subscribers":[null],"_isLeaf":true,"_values":[false]},"hidden":{"_subscribers":[null],"_values":[false],"_dependencies":[{"_subscribers":[null,null,null],"_isLeaf":true,"_values":["all"]}]}},{"title":"Test2","checked":{"_subscribers":[null],"_isLeaf":true,"_values":[true]},"hidden":{"_subscribers":[null],"_values":[false],"_dependencies":[{"_subscribers":[null,null,null],"_isLeaf":true,"_values":["all"]}]}}]}';
//This json is stuff that I pulled from the file that the Push function created.

var todoList = Observable();
todoList = JSON.parse(json); //This doesn't work.
var titleInput = Observable("");
var currentTab = Observable("all");

var remainingCount = todoList.count(function(x){
    return x.checked.not();
});

var remainingText = remainingCount.map(function(x){
    return x + " " + ((x == 1) ? "task" : "tasks") + " remaining";
});

var canClearCompleted = todoList.count(function(x){
    return x.checked;
}).map(function(x){
    return x > 0;
});

function addItem(arg) {
    todoList.add(new Task(titleInput.value));
    Push();
}

function deleteItem(arg){
    todoList.tryRemove(arg.data);
    Push();
}

function toggleAll(arg) {
    var remaining = remainingCount.value;
    todoList.forEach(function(x){
        x.checked.value = (remaining == 0) ? false : true;
    });
    Push();
}

function toggleItem(arg) {
    arg.data.checked.value = !arg.data.checked.value;
    Push();
}

function clearCompleted() {
    todoList.removeWhere(function(x) { return x.checked.value; });
    Push();
}

function showAll() {
    currentTab.value = "all";
}

function showActive() {
    currentTab.value = "active";
}

function showCompleted() {
    currentTab.value = "completed";
}

module.exports = {
    todoList: todoList,
    titleInput: titleInput,
    currentTab: currentTab,
    remainingText: remainingText,
    canClearCompleted: canClearCompleted,
    addItem: addItem,
    deleteItem: deleteItem,
    toggleAll: toggleAll,
    toggleItem: toggleItem,
    clearCompleted: clearCompleted,
    showAll: showAll,
    showActive: showActive,
    showCompleted: showCompleted
};

Made some more changes and added back a for i loop but still having issues!

var Observable = require("FuseJS/Observable");
var Storage = require("FuseJS/Storage");

function Task(title){
    var self = this;
    this.title = title;
    this.checked = Observable(false);
    this.hidden = Observable(function(){
        if (currentTab.value == "all"){
            return false;
        }
        else if (currentTab.value == "active"){
            return self.checked.value ? true : false;
        }
        else {
            return self.checked.value ? false : true;
        }
    });
}

function Push() {
    var string = "module.exports = " + JSON.stringify(todoList);
    Storage.write("todoListJSON", string);
}

var json = {"_subscribers":[null],"_isLeaf":true,"_values":[{"title":"Test","checked":{"_subscribers":[null],"_isLeaf":true,"_values":[true]},"hidden":{"_subscribers":[null],"_values":[false],"_dependencies":[{"_subscribers":[null,null,null],"_isLeaf":true,"_values":["all"]}]}},{"title":"Test1","checked":{"_subscribers":[null],"_isLeaf":true,"_values":[false]},"hidden":{"_subscribers":[null],"_values":[false],"_dependencies":[{"_subscribers":[null,null,null],"_isLeaf":true,"_values":["all"]}]}},{"title":"Test2","checked":{"_subscribers":[null],"_isLeaf":true,"_values":[true]},"hidden":{"_subscribers":[null],"_values":[false],"_dependencies":[{"_subscribers":[null,null,null],"_isLeaf":true,"_values":["all"]}]}}]};
//var parsed = JSON.parse(json);

var todoList = Observable();
var titleInput = Observable("");
var currentTab = Observable("all");

for (var i = 0; i < json._values.length; i++) {
    todoList.add(new Task(json._values.i.title));
    i.data.checked.value = json._values.i.checked.value;
}

var remainingCount = todoList.count(function(x){
    return x.checked.not();
});

var remainingText = remainingCount.map(function(x){
    return x + " " + ((x == 1) ? "task" : "tasks") + " remaining";
});

var canClearCompleted = todoList.count(function(x){
    return x.checked;
}).map(function(x){
    return x > 0;
});

function addItem(arg) {
    todoList.add(new Task(titleInput.value));
    Push();
}

function deleteItem(arg){
    todoList.tryRemove(arg.data);
    Push();
}

function toggleAll(arg) {
    var remaining = remainingCount.value;
    todoList.forEach(function(x){
        x.checked.value = !x.checked.value;
    });
    Push();
}

function toggleItem(arg) {
    arg.data.checked.value = !arg.data.checked.value;
    Push();
}

function clearCompleted() {
    todoList.removeWhere(function(x) { return x.checked.value; });
    Push();
}

function showAll() {
    currentTab.value = "all";
}

function showActive() {
    currentTab.value = "active";
}

function showCompleted() {
    currentTab.value = "completed";
}

module.exports = {
    todoList: todoList,
    titleInput: titleInput,
    currentTab: currentTab,
    remainingText: remainingText,
    canClearCompleted: canClearCompleted,
    addItem: addItem,
    deleteItem: deleteItem,
    toggleAll: toggleAll,
    toggleItem: toggleItem,
    clearCompleted: clearCompleted,
    showAll: showAll,
    showActive: showActive,
    showCompleted: showCompleted
};

Change this:

var todoList = Observable();
todoList = JSON.parse(json); 

To this:

var todoList = Observable();
todoList.value = JSON.parse(json);

Or even shorter:

var todoList = Observable(JSON.parse(json));

Doesn’t work. Launches but it doesn’t show anything and when I click it crashes saying ‘Cannot read property ‘value’ of undefined.’ What am i doing wrong

var Observable = require("FuseJS/Observable");
var Storage = require("FuseJS/Storage");

function Task(title){
    var self = this;
    this.title = title;
    this.checked = Observable(false);
    this.hidden = Observable(function(){
        if (currentTab.value == "all"){
            return false;
        }
        else if (currentTab.value == "active"){
            return self.checked.value ? true : false;
        }
        else {
            return self.checked.value ? false : true;
        }
    });
}

function Push() {
    var string = "module.exports = " + JSON.stringify(todoList);
    Storage.write("todoListJSON", string);
}

var json = '{"_subscribers":[null],"_isLeaf":true,"_values":[{"title":"Test","checked":{"_subscribers":[null],"_isLeaf":true,"_values":[true]},"hidden":{"_subscribers":[null],"_values":[false],"_dependencies":[{"_subscribers":[null,null,null],"_isLeaf":true,"_values":["all"]}]}},{"title":"Test1","checked":{"_subscribers":[null],"_isLeaf":true,"_values":[false]},"hidden":{"_subscribers":[null],"_values":[false],"_dependencies":[{"_subscribers":[null,null,null],"_isLeaf":true,"_values":["all"]}]}},{"title":"Test2","checked":{"_subscribers":[null],"_isLeaf":true,"_values":[true]},"hidden":{"_subscribers":[null],"_values":[false],"_dependencies":[{"_subscribers":[null,null,null],"_isLeaf":true,"_values":["all"]}]}}]}';

var todoList = Observable();
var titleInput = Observable("");
var currentTab = Observable("all");

todoList.value = JSON.parse(json);

var remainingCount = todoList.count(function(x){
    return x.checked.not();
});

var remainingText = remainingCount.map(function(x){
    return x + " " + ((x == 1) ? "task" : "tasks") + " remaining";
});

var canClearCompleted = todoList.count(function(x){
    return x.checked;
}).map(function(x){
    return x > 0;
});

function addItem(arg) {
    todoList.add(new Task(titleInput.value));
    Push();
}

function deleteItem(arg){
    todoList.tryRemove(arg.data);
    Push();
}

function toggleAll(arg) {
    var remaining = remainingCount.value;
    todoList.forEach(function(x){
        x.checked.value = !x.checked.value;
    });
    Push();
}

function toggleItem(arg) {
    arg.data.checked.value = !arg.data.checked.value;
    Push();
}

function clearCompleted() {
    todoList.removeWhere(function(x) { return x.checked.value; });
    Push();
}

function showAll() {
    currentTab.value = "all";
}

function showActive() {
    currentTab.value = "active";
}

function showCompleted() {
    currentTab.value = "completed";
}

module.exports = {
    todoList: todoList,
    titleInput: titleInput,
    currentTab: currentTab,
    remainingText: remainingText,
    canClearCompleted: canClearCompleted,
    addItem: addItem,
    deleteItem: deleteItem,
    toggleAll: toggleAll,
    toggleItem: toggleItem,
    clearCompleted: clearCompleted,
    showAll: showAll,
    showActive: showActive,
    showCompleted: showCompleted
};

I think your problem here is that you are using JSON.stringify directly on the Observable, and so you end up with a serialized version of Observable (+ your data). I dont think going back with JSON.parse is going to give you the same data structure (with Observables) as you had originally.

One way around this is to serialize and deserialize your objects yourself:

Say i had the following class:

function Person(name, age)
{
    this.name = name;
    this.age = age;
}
var people = Observable(new Person("James", 40), new Person("Bond", 20));

You could then serialize and deserialize the “people” observable like so:

function serializePerson(p)
{
    return "{ \"name\" : " + p.name + ", \"age\":" + p.age + "}";
}
function serializePeople()
{
    var json = "\"people\" : [";
    people.forEach(function(p)
    {
        json += serializePerson(p) + ","
    });
    json += "]";
    return json;
}

var people = Observable();
function deserializePeople(peopleJson)
{
    var parsed = JSON.parse(peopleJson);
       for (var i = 0; i < parsed.people.length; i++)
    {
        var person = parsed.people[i];
        people.add(new Person(person.name, person.age));
    }
}

  • Note that this code is more like pseudo code (i havent tested it), but i hope you get the idea. I’m also not even sure this is the best way of doing stuff like this, but it has worked for me :slight_smile:

I don’t know how but I managed to do it. thanks so much!!! You are amazing and super cool dude! Excellent example on serialization and deserialization! This really helped me! Do you want the apk of the app that I am creating? I would be glad to give it to you!