Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Why a reference to object is replaced with its value

Why a reference to object is replaced with its value

Problem

I use node.js and express.

I saved on the 'req.session' a complex object that includes array of objects. In addition I save reference to one of the objects in the array. For example:

var value = {
    name: "name"
    , values: []
};

req.session.value = value;

//
// I populate 'req.session.value' with values (with the same structure)
//

// then I save reference to one of the inner objects

var currentValue = req.session.value[3];

//
// later I try to change the save object
//

currentValue.name = "newName";

I expected that if I change the 'currentValue' then the 'req.session.value[3]' will be changed as well. However, for some reason it doesn't happen.

To be concrete, if I change the currentValue immediately after I assign it then the req.session.value[3] is changed but if I am doing it in the next call then just the currentValue is changed.

In the example: I do the assignments to the 'req.session' in the "app.get(...)" if I change the value of the currentValue in the "app.get(...)" it is run ok (the value change in both places) but if I change it in the 'app.post(...)' the only object that change is the currentValue while the req.session.value[3] left the same.

Thanks in advance,
Shai

The code:

'app.get("/template/:templateid/feature/add", isTemplate, function(req, res) {'
'    if (!req.session.features) { // if features empty'
''
'    // Save the first features level from the current template in the session '
'    req.session.features = req.session.template.feature;'
'    //'
'    if (!req.session.featureNodes) { // featureNotes is a stack/branch of the features'
'        req.session.featureNodes = [];'
'    }'
'    if (!req.query.featureroot || req.query.featureroot == "") {'
'    } else {'
'        var featureRoot = getFeature(req.query.featureroot, req.session.features); // get one object from req.session.features'
'        if (featureRoot) {'
'            req.session.featureNodes.push(featureRoot);     // save reference'
'            var featureR = req.session.featureNodes.pop();  // do check that work!'
'            var values = {'
'                name: "req.body.name"'
'                , description: "req.body.description"'
'                , wieght: "req.body.wieght"'
'                , created: new Date()'
'                , modified: new Date()'
'                , feature: []'
'            };'
''
'            featureR.feature.push(values); // also req.session.features changed'
'            req.session.featureNodes.push(featureRoot); // push the reference back for use later'
'        }      '
'    }'
'    res.render("addfeature2template.jade", { '
'        title: "Add new feature"'
'        ,template: req.session.template'
'        ,feature: req.session.featureNodes'
'    });'
'});'
''
'app.post("/feature/add", isUser, function(req, res) {'
'    var SUBMIT = "Create";'
'    var CANCEL = "Cancel";'
'    switch ( req.param("feature") ) {'
'        case SUBMIT:'
'            var fields = {  name: 1, description: 1, wieght: 1};'
'            var values = {'
'                name: req.body.name'
'                , description: req.body.description'
'                , wieght: req.body.wieght'
'                , created: new Date()'
'                , modified: new Date()'
'                , feature: []'
'            };'
'            if (req.session.featureNodes.length 
Problem courtesy of: user1798168

Solution

req.session object is serialized (to store) between the requests.

Example:

Request 1:

req.session = {};
var a = { hello : 'world' };
var b = a;
req.session.a = a;
req.session.b = b;

In this context variables a, b, req.session.a, req.session.b points to one object. You can change field hello in any of these objects, and this will to change in each of them.

After end of request req.session object will be serialized for session storage (memcached, mongodb, etc).

Request 2:

Before request 2 req.session object will be deserialized from storage. Now it contains plain values without references. You can access req.session.a and req.session.b but now it two different objects.

Solution courtesy of: Vadim Baryshev

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

Why a reference to object is replaced with its value

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×