Message queue node that can be indexed

Well you first should try to get it from context... which I think you are doing.....

var queue_array = flow.get("queue")     //  I'm guessing this checks if the array exists.

but then at the end you have to save it back to context... otherwise next time it won't be there...

Woo - hoo!

I think that was lucky of me as I just worked that out - I think.

I added this to the end of the block:

But the output I am seeing is not understandable.

Oh, after looking a bit harder, I think I get it.

I'll apply it to the other node I am actually using and see if it helps.

Ok, I think I have one part of it working.

But now I can't wipe the array when I want to. I have accidentally saved 15 entries and can't wipe them.

I thought the command would be queue_array = []; because that was what I had before when it kept getting wiped.

This is a snip-it of the code:

    if (msg.payload == "WIPE ALL")
        //  Wipe the whole array
    node.warn("Initialising array");
    queue_array = [];

This is what is telling me the array isn't being wiped.

let index = context.get('SIZE') || 0;   //  I hope this part works.  (See below)
node.warn("Index size from context " + index);
index = queue_array.length;             //  This should get the *length* of the array.
node.warn("Index size from array " + index);

I see 0 then for the second line I see 15.

So I am still missing something.

Pop is covered in the link that I gave. Just after map and before push.

You didn't write it back again so you didn't save the change.

D'oh! Yeah. Silly me.
I really must make idiots look smart.

You have some other logic issues too. As your code stands, you will never have a next will you? That's because you are adding to the queue after your other logic, I think that you need to add to it first?

The idea is that things are put in the array.
As they are put in, the only one I can really use is the previous one.

But :wink:

I scroll back a few entries and what ever. I may want to go to the next entry too.

I'm working on it. Found quite a few problems with how the pointers are kept, etc.

Be Back Soon.

Ok, I'm stuck.

node.warn("Next entry " + i+1);

Doesn't work.

I get 11 if i = 1.

Is there a way - without introducing a new variable to get it to show i+1?

This flow works - as best I can tell.

The node counters are NOT zero counting which I think helps with seeing which message you are viewing.

Could you help me with a more tidy way with the variable j in the scheme of things.

That doesn't mean directly you. But more a general request for help.
Sorry the main function node still has a bit of old stuff in it.

That's the node with the j variable in it.
The node shows how many entries in the array. NOT zero counting.
So as the node shows the index number, I wanted it to also be non-zero counting.

Found a couple of spelling mistakes.

[{"id":"8e458e68.2f8d88","type":"function","z":"184dc884.7aba5f","name":"Array","func":"//\nvar output = \"\";                        //  This is what returns the indexed value.\nvar i = context.get('pointer') || 0;\nvar j = 0;\nvar queue_array = flow.get(\"queue\")     //  I'm guessing this checks if the array exists.\nif (!Array.isArray(queue_array))\n{\n    //  If not, set up array.\n    node.warn(\"Initialising array\");\n    queue_array = [];\n    flow.set('queue',queue_array);\n    node.warn(\"Array set up.\");\n}\n\nsize = queue_array.length;\n\nif (msg.topic == \"CONTROL\")\n{\n    //  Stuff to be done with  array.\n    if (msg.payload == \"NEXT\")\n    {\n        //  Display next item\n        i = i + 1;\n        j = i + 1;\n        node.warn(\"Next entry \" + j);\n        output = queue_array[i];\n        msg.payload = output;\n        context.set('pointer',i);               //  Save the value.\n        node.status(size + \" \" + j);\n        return msg;\n    } else\n    if (msg.payload == \"PREVIOUS\")\n    {\n        //  Display previous item\n        i = i - 1;\n        j = i + 1;\n        node.warn(\"Previous entry \" + j);\n        output = queue_array[i];\n        msg.payload = output;\n        context.set('pointer',i);               //  Save the value.\n        node.status(size + \" \" + j);\n        return msg;\n    } else\n    if (msg.payload == \"WIPE\")\n    {\n        //  Delete this item\n    } else\n    if (msg.payload == \"WIPE ALL\")\n    {\n        //  Wipe the whole array\n    node.warn(\"Initialising array\");\n    queue_array = [];\n    flow.set('queue',queue_array);\n    node.warn(\"Array Wiped.\");\n    return;\n    }\n}\n\nnode.warn(\"saving data to array\");\n\nqueue_array.push(msg.payload);\n\nsize = queue_array.length;\n\ncontext.set('pointer',i);               //  Save the value - for what ever reason.\n\nflow.set('queue',queue_array);\nnode.status(size + \" \" + pointer);\n\nreturn;\n","outputs":1,"noerr":0,"x":490,"y":1320,"wires":[["e09fc19c.cf203"]]},{"id":"c0ef557b.139f1","type":"template","z":"184dc884.7aba5f","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Message {{payload}}","output":"str","x":230,"y":1280,"wires":[["8e458e68.2f8d88","fcb9dca0.971b5"]]},{"id":"e09fc19c.cf203","type":"debug","z":"184dc884.7aba5f","name":"Index result","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":650,"y":1320,"wires":[]},{"id":"c4bbdffc.81ab78","type":"inject","z":"184dc884.7aba5f","name":"Next","topic":"CONTROL","payload":"NEXT","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":1360,"wires":[["8e458e68.2f8d88"]]},{"id":"16235d1e.a6c2db","type":"inject","z":"184dc884.7aba5f","name":"Previous","topic":"CONTROL","payload":"PREVIOUS","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":1390,"wires":[["8e458e68.2f8d88"]]},{"id":"8d565471.b8f5a","type":"inject","z":"184dc884.7aba5f","name":"Wipe All","topic":"CONTROL","payload":"WIPE ALL","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":1470,"wires":[["8e458e68.2f8d88"]]},{"id":"bb6554dd.38b188","type":"inject","z":"184dc884.7aba5f","name":"Wipe","topic":"CONTROL","payload":"WIPE","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":1440,"wires":[["8e458e68.2f8d88"]]},{"id":"26162964.640a16","type":"random","z":"184dc884.7aba5f","name":"Random number","low":"1","high":"10","inte":"true","property":"payload","x":200,"y":1250,"wires":[["c0ef557b.139f1"]]},{"id":"fcb9dca0.971b5","type":"debug","z":"184dc884.7aba5f","name":"History","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":500,"y":1230,"wires":[]},{"id":"638c9635.68a788","type":"inject","z":"184dc884.7aba5f","name":"Add new item to array","topic":"","payload":"blah_","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":1220,"wires":[["26162964.640a16"]]}]

And this is for the single wipe part of the function node code:

        //  Delete this item
        j = i + 1;
        node.warn("Removing item " + j + " which is " + queue_array[i]);
        flow.set('queue', queue_array);

All seems to work as I want.

(Just copy/paste this in the code at the delete this item part is. Which as posted is basically empty.)

Could someone give it a sanity check?

The problem here is JavaScript uses the + symbol for both joining strings and adding numbers.

Because your statement has a string in it (the "Next entry " part), it will assume it should treat everything as a string, so the 1 ends up being 11 - just as 8 would end up as 81.

The trick is to give the JavaScript interpreter a hint as to what order it should do the operations. I see you've used spaces in your statement, but you need to use brackets:

node.warn("Next entry " + (i+1) );

With those brackets, it will first do the i+1- where both sides are numbers, so it does numeric addition. It then does "Next entry " + <result of (i+1)> where there is a String, so it does a string join.

I hope that clarifies it.

1 Like

Yes, thanks Nic.

I was suspicious of doing that. It is I have just spent the last . . . . (long time) getting this working and am starting to lose self belief.

I'll go in and modify the code now.

That kind of lies with the old BASIC syntax. But . . . . . I am good at messing things up and just hadn't got around to trying that.

Self doubt isn't a good thing.

I've posted the working flow here if you want to look at it and have a look at what I did.

Working flow

Since we should all now be using newer versions of Node.js, we can also make use of ES6 features. So a nice way to output a string with an embedded simple calculation is:

node.warn( `Next entry ${i+1}` );

Note the backticks

1 Like

I think us JS muggles should stick with the simplest way of doing something :slight_smile:

You wizards can do things the fancy ways :slight_smile:

1 Like

Haha, I would argue that, in this case, the fancy way may well be the easiest :grinning:

Anyway, it is through learning new ways that we keep ourselves youthful - or "childish" as our better halves would doubtless characterise things. :rofl: