Class atributes not updating [node.js - express ]

683 Views Asked by At

I have some troubles with a .js Object's atribute which is not updating when i ask it to.

I'm new in the javascript world, so i hope my issue won't be tricky.

First of all, this is a part of my Node class :

Node = function (label, vals, db, callback) {
    // attributes
    this.label = label;
    this.vals = vals;
    this.db = db;
    if (typeof calback == 'function') calback();
}
Node.prototype.insert_db = function (calback) {
    var vals = this.vals;
    // Create a node 
    console.log("1:"); // output print
    console.log(vals); // output print
    this.db.save(vals, function (err, node) {
        if (err) throw err;
        vals = node;
        console.log("2:"); // output print
        console.log(vals); // output print
    });
    this.vals = vals;
    console.log("3:"); // output print
    console.log(this.vals); // output print
    if (typeof calback == 'function') calback();
}

what i want to do with this code, is to update the "id" value of a my Node object after insertion. But... here is my console.log after runing this code :

var per = new Node('Whatever', { firstName: "aaaa", lastName: "aaaa", age: "aaaa" }, db2);
per.insert_db();

Console output :

1:
{ firstName: 'aaaa', lastName: 'aaaa', age: 'aaaa' }
3:
{ firstName: 'aaaa', lastName: 'aaaa', age: 'aaaa' }
2:
{ firstName: 'aaaa', lastName: 'aaaa', age: 'aaaa', id: 491 }

The 3rd state is (in second position) never get updated. I don't know where it comes from. I've spent the last 2 days on that problem, that i obviously can't handle anymore.

Thanks in advance.

EDIT Still having troubles. Thanks to @MarkHughes, here is my new code

Node.prototype.insert_db = function (callback) {
    var temp = this;
    this.db.save(this.vals, function (err, node) {
        if (err) throw err;
        temp.vals = node;
        console.log(temp.vals); // output print
        if (typeof callback == 'function') callback();
    });
}

Code ran by this one

var per = new Node('Person', { firstName: "aaaa", lastName: "aaaa", age: "aaaa" }, db2);
per.insert_db(res.render('login-index', { title: 'miam', dump: mf.dump(per) }));

Now here are the console.log(temp.vals)

{ firstName: 'aaaa', lastName: 'aaaa', age: 'aaaa', id: 515 }

And here is the rendered output (pre html) :

vals:  object(3): {
    firstName:  string(4): "aaaa"
    lastName:  string(4): "aaaa"
    age:  string(4): "aaaa"
}

The output is in the callback function wich is in the asynchronous function .save... And still no update. :(

I don't know if this helps, for debug only :

setTimeout(function() { console.log(temp) }, 3000);

written after the .save function returns this :

[...]
vals: { firstName: 'aaaa', lastName: 'aaaa', age: 'aaaa', id: 517 },
[...]

What am I doing wrong ?

1

There are 1 best solutions below

7
Mark Hughes On BEST ANSWER

.save is asynchronous, so you can't use the value returned by it outside its callback, hence moving the rest of your code inside the callback will fix it:

var t = this;
this.db.save(vals, function (err, node) {
    if (err) throw err;
    vals = node;
    console.log("2:"); // output print
    console.log(vals); // output print

    t.vals = vals;
    console.log("3:"); // output print
    console.log(t.vals); // output print
    if (typeof calback == 'function') calback();
});

Saving "this" into a variable allows access to it from inside the callback.

For your calling code, you need to ensure you are rendering the output in the callback from insert_db() - e.g. something like:

per.insert_db(function () { 
    res.render('login-index', { title: 'miam', dump: mf.dump(per) })
});

Note that you have to wrap res.render in a function() else what will be passed in as the callback will be the return value of executing that function, rather than the function itself.