Node if statement execution order - node.js

I am confused why this if statement will throw a JS error. Why isn't the function running as soon as it returns true?
res.locals.user = null;
console.info(res.locals.user === null); //true
if (res.locals.user === null && res.locals.user.level > 5) {

The && in your if statement is analogous to this:
res.locals.user = null;
console.info(res.locals.user === null); //true
if (res.locals.user === null) {
// at this point you know that res.locals.user is null
if (res.locals.user.level > 5) {
// won't get here because res.locals.user.level will throw an exception
}
}
If the first part of an && comparison evaluates to truthy, then the second part will also be evaluated since for the whole statement to be true, both pieces of the statement must be truthy.
It appears that you may want this instead:
res.locals.user = null;
console.info(res.locals.user === null); //true
if (res.locals.user === null || res.locals.user.level > 5) {
// will get here because only the first term will be evaluated
// since when the first term evaluates to true, the || is already satisfied
}
Or since I'm not quite sure which logic you want, maybe you wanted this:
res.locals.user = null;
console.info(res.locals.user === null); //true
if (res.locals.user !== null && res.locals.user.level > 5) {
// will not get here because res.locals.user doesn't pass the first test
// won't throw an exception because 2nd term won't be evaluated
}

Because the first part of the evaluation is true, so it goes on to evaluate the next part which will then always throw an exception as the first part was true. It's like a paradox :)
There are languages where the the && only executes the second comparison if the first is true (like java). However, what you wrote would fail in any language. You can't be null and level>5 all at once.

Related

Combining nested conditional logical operators

I was wondering if any can help point me to resource to teach me more about logical operators, and answer a question for me. I would like (for the sake of satisfying my curiosity) to combine these nested conditional checks with logical operators into one statement.
if(obj1 != null && obj2 != null) {
if(obj1 != undefined && obj2 != undefined) {
//do something here
}
}
I have tried
if((obj1 != null || obj1 != undefined) && (obj2 != null || obj2 != undefined)) {
//do something here
}
But I don't think that works, since if obj1 or obj2 is equal to null or undefined than the or statement will evaluate to true. So the above code in the conditional would be executed if obj1 was null or undefined AND obj2 was null or undefined, which is definitely not what I want.
So how could I combine the nested conditional into one line?
Thanks!
:)
You might be overthinking. Code like
if (a) {
if (b) {
// stuff
}
}
executes stuff only if a and b are both true, so it is simply equivalent to
if (a && b) {
// stuff
}
Thus all you have to do is take your existing conditions and connect them with &&. You can write
if((obj1 != null && obj2 != null) && (obj1 != undefined && obj2 != undefined)) {
//do something here
}

Prevent a new block from being attached to the same type if the target is used as a StatementInput

I basically have two types of blocks: a rule block and a fact block (just like in Prolog). They can both be attached to each other. The rule block expects two inputs of the type 'fact'.
However, it should not be possible to have multiple attached fact blocks as a single input. Therefore I had to set 'setNextStatement' to false whenever a fact block is attached as input of a rule block.
This is what I tried to do in the fact block:
this.setOnChange(function(changeEvent) {
if(changeEvent.type == Blockly.Events.MOVE) {
let prevBlock = this.getPreviousBlock();
if(prevBlock != null && prevBlock.type == "rule") {
let nextBlock = prevBlock.getNextBlock();
if((nextBlock != null && nextBlock != this) || (nextBlock == null)) {
this.setNextStatement(false);
}
} else {
this.setNextStatement(true);
}
}
});
And of course the rule block:
Blockly.Blocks['rule'] = {
init: function() {
this.appendDummyInput("RULE_DATA")
.appendField('Rule: ');
this.appendStatementInput('INPUT_HEAD')
.setCheck("fact")
.appendField("Head");
this.appendStatementInput('INPUT_BODY')
.setCheck("fact")
.appendField("Body");
...
This actually works, but when I separate a fact from the input part of a rule, I always get the following error:
Uncaught Error: Connection lists did not match in length.
at Blockly.BlockSvg.Blockly.Block.getMatchingConnection (blockly_compressed.js:1447)
at Blockly.InsertionMarkerManager.connectMarker_ (blockly_compressed.js:1125)
at Blockly.InsertionMarkerManager.showPreview_ (blockly_compressed.js:1118)
at Blockly.InsertionMarkerManager.maybeShowPreview_ (blockly_compressed.js:1117)
at Blockly.InsertionMarkerManager.update (blockly_compressed.js:1110)
at Blockly.BlockDragger.dragBlock (blockly_compressed.js:1130)
at Blockly.TouchGesture.Blockly.Gesture.startDraggingBlock_ (blockly_compressed.js:1177)
at Blockly.TouchGesture.Blockly.Gesture.updateIsDraggingBlock_ (blockly_compressed.js:1174)
at Blockly.TouchGesture.Blockly.Gesture.updateIsDragging_ (blockly_compressed.js:1176)
at Blockly.TouchGesture.Blockly.Gesture.updateFromEvent_ (blockly_compressed.js:1171)
Does somebody has any idea?
Hi you need is just override the getMatchingConnection function from blockly and comment the check in the function
window.Blockly.Block.prototype.getMatchingConnection = function(otherBlock, conn) {
var connections = this.getConnections_(true);
var otherConnections = otherBlock.getConnections_(true);
// if (connections.length !== otherConnections.length) {
// throw Error("Connection lists did not match in length.");
// }
for (var i = 0; i < otherConnections.length; i++) {
if (otherConnections[i] === conn) {
return connections[i];
}
}
return null;
};

Cheking if variable is undefined

So I want to check if a variable is undefined in node.js. So far I work like this:
if(typeof object.data.items[1] === 'undefined')
{
break;
}
else
{
console.log("Defined");
}
But it gives me this error:
"TypeError: Cannot read property 'data' of undefined".
Any ideas on how to bypass this error while still checking if it's undefined?
check both object and object.data is defined first.
if(object && object.data && typeof object.data.items[1] === 'undefined')
{
break;
}
else
{
console.log("Defined");
}
or
if(!object || !object.data || typeof object.data.items[1] === 'undefined')
{
break;
}
else
{
console.log("Defined");
}
It seems that object variable is undefined too. Try the following code:
if(
typeof object === 'undefined' ||
typeof object.data === 'undefined' ||
typeof object.data.items[1] === 'undefined')
{
break;
}
else
{
console.log("Defined");
}
if(!_.get(object,['data','items',1]))
{
break;
}
When you try to access a property of JSON object you have to ensure that left side of your dot operator must have some value but not undefined or null. i.e.
If you want to access a.b.c.d then you have to make sure that each left side property has some value. You can use #rijin's answer.

check many req.body values (nodejs API)

Is there a good, efficient way to check many req.body values whether they are not undefined or null?
At most I have about 17 values to check.
You can create a function that takes a list of property names and checks to see if they have values other than null or undefined.
// checks to see if all props in the list are available and non-null
// list can either be an array or a | separated string
function checkProps(obj, list) {
if (typeof list === "string") {
list = list.split("|");
}
for (prop of list) {
let val = obj[prop];
if (val === null || val === undefined) {
return false;
}
}
return true;
}
Then, you could use it like this:
if (!checkProps(req.body, "email|firstName|lastName|address1|city|state|zip")) {
// some properties missing
} else {
// all properties available
}

Comparing pointers fails mystically in VC++

I have a tree structure and I want to find all nodes matching a given criteria. Each time I call the find function, it returns next matching node. Children are searched by recursive function call.
For some reason a key comparison of pointers fails for this implementation. Please see the code below, I have pointed out the failing comparison.
HtmlTag* HtmlContent::FindTag(string tagName, string tagParameterContent)
{
if (tagName.empty() && tagParameterContent.empty())
return NULL;
if (this->startTag == NULL)
return NULL;
this->findContinue = this->FindChildren(this->startTag, &tagName, &tagParameterContent);
return this->findContinue;
}
HtmlTag* HtmlContent::FindChildren(HtmlTag* firstTag, string* tagName, string* tagParameterContent)
{
HtmlTag* currentTag = firstTag;
HtmlTag* childrenFound = NULL;
while (currentTag != NULL)
{
if (!tagName->empty() && *tagName == currentTag->tagName)
{
if (tagParameterContent->empty() || currentTag->tagParameters.find(*tagParameterContent, 0) != -1)
{
if (this->findContinue == NULL)
break; // break now when found
else if (this->findContinue == currentTag) // TODO why this fails?
this->findContinue == NULL; // break on next find
}
}
if (currentTag->pFirstChild != NULL)
{
childrenFound = this->FindChildren(currentTag->pFirstChild, tagName, tagParameterContent);
if (childrenFound != NULL)
{
currentTag = childrenFound;
break;
}
}
currentTag = currentTag->pNextSibling;
}
return currentTag;
}
VC++ compiler accepts this code but for some reason I can't put a breakpoint on this comparison. I guess this is optimized out, but why? Why this comparison fails?
I think that you shoud replace == with = in assignment after comparison. Compiler optimalized this whole section because it doesnt do anything useful.

Resources