Trouble storing time in flow variable

I am trying to store time variables in flow variables. And somehow it's not working. When I test with node.warn, everything seems ok. Also when I store actual time, it's ok. So I am puzzled here. Can anybody help me out?

msg_p = {};
msg_period = {};
msg_datepick = {};
let h, m, y, val, period, d;

// Start up
if (msg.topic == "boot"){
}

flow.set('overview.actualtime', new Date());    
// Button today pushed
if (msg.topic == "today"){
    period = "today";
    flow.set('overview.period', period);    
    // Set new starttime    
    d = new Date();
    d.setHours(0);
    d.setMinutes(0);
    d.setSeconds(0);
node.warn("starttime = "+d);
    flow.set('overview.starttime', d);    
    // Set new endtime    
    d.setHours(23);
    d.setMinutes(59);
    d.setSeconds(59);
node.warn("endtime = "+d);
    flow.set('overview.endtime', d);    
}

The result in flow variables is,

afbeelding

as you can see, starttime and endtime are the same here.

afbeelding

In node.warn the result looks good.

:face_with_raised_eyebrow:

I tried it another way, and now the node.warn is also wrong, same as flow variables.

msg_p = {};
msg_period = {};
msg_datepick = {};
let h, m, y, val, period, d, ds, de;

// Start up
if (msg.topic == "boot"){
}

flow.set('overview.actualtime', new Date());    
// Button today pushed
if (msg.topic == "today"){
    period = "today";
    flow.set('overview.period', period);    
    // Set new starttime    
    d = new Date();
    d.setHours(0);
    d.setMinutes(0);
    d.setSeconds(0);
    ds = d;
    // Set new endtime    
    d.setHours(23);
    d.setMinutes(59);
    d.setSeconds(59);
    de = d;
node.warn("starttime = "+ds);
node.warn("endtime = "+de);
    flow.set('overview.starttime', ds);    
    flow.set('overview.endtime', de);    
}

afbeelding

This is due to JS storing objects by reference. you have set endtime and starttime to refer to the same object. When you update the object starttime refers to, then when you update endtime you update the same object. Simple fix is to use different Date vars

msg_p = {};
msg_period = {};
msg_datepick = {};
let h, m, y, val, period, ds, de;

// Start up
if (msg.topic == "boot"){
}

flow.set('overview.actualtime', new Date());    
// Button today pushed
if (msg.topic == "today"){
    period = "today";
    flow.set('overview.period', period);    
    // Set new starttime    
    ds = new Date();
    ds.setHours(0);
    ds.setMinutes(0);
    ds.setSeconds(0);
node.warn("starttime = "+ds);
    flow.set('overview.starttime', ds);    
    // Set new endtime    
    de = new Date();
    de.setHours(23);
    de.setMinutes(59);
    de.setSeconds(59);
node.warn("endtime = "+de);
    flow.set('overview.endtime', de);    
}
return null;
1 Like

@E1cid , yes, indeed, now I understand. I already knew for copying objects (deep copying). But did not connect the dots, this is also an object. Thanks very much, helpt me a lot.

1 Like

Somewhat of a dated tutorial now. There are other, better methods to create a clone from ES6 onwards.

The link was more for the OP to understand how objects are stored by reference, not for the cloning technics. If you wish to add a link for better cloning methods feel free.

@TotallyInformation, @E1cid, yes, I read the article, it was very technical, but I understand a bit.
I think copying objects in javascript is a weard thing though. I know the concept of alliasing, that's very clear.
But normal copying of objects in javascript is a mix of copying and aliassing.

I use then:

flow.set('dest', JSON.parse(JSON.stringify(source))); // Deep copy);

But now I have another mistery on my hands with the same subject I think.
Maybe you can help me out with that also, here is the code,

let test = {};
let a,b,c;

a=1;
b=2;
c=3;

// This is working
test.a = a;
test.b = b;
test.c = c;

// This is NOT working
//test.item.a = a;
//test.item.b = b;
//test.item.c = c;

flow.set('test', JSON.parse(JSON.stringify(test))); // Deep copy);

//flow.set('dest', JSON.parse(JSON.stringify(source))); // Deep copy);

//node.warn(test);
//node.warn(typeof test);

return msg;

If I use test.item.a/b/c, I get this warning,
afbeelding

What I am trying to do , is build a complex object, and then (deep) copy the complete object to flow.
But if I write each (complex) variable separete to flow it is working, but I don't know if that is referenced then or a real copy.

This is working:

flow.set('test.item.a', a );

That will fail because test.item does not exist, so you cannot set a property in it. If you first did
test.item = {}
then it should be ok.

@Colin , indeed, but then I have to define every object in an object, but if I do like this,

flow.set('test.item.a', a );

It is working.
So writing each variable seperately????
if I am working this way, is it a copy or a reference?

You could use Object.assign() - JavaScript | MDN to add to the stored object.

or

let key  = "a";
let a = "a value";
flow.set('test.item.' + key, a );

@E1cid , your solution might be working, I also read the article you pointed out, but that doesn't make live easier.
I like simple code. So I think I opt for the solution to copy each variable seperately.

Make absolutely certain that you wrap that line in a try/catch block for when it fails. JSON parsing is very fragile. It is generally better to use something like flow.set('test', Object.assign({}, test))

@TotallyInformation, I guess you speak from experience, so I will replace that construct at the places I used it. Thanks very much for the info so far.

Also thanks @E1cid and @Colin for your input.
I am still learning every day!! :grinning: :grinning:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.