Why do some node properties give me undefined when I log them? - javascript

I have an endpoint in my node app and I am doing the following...
app.put('/api/authentication', function(req,res){
console.log(global.ff); //undefined
console.log(req.ff); //undefined
console.log(blah); //throws error
});
I don't understand why the first two give me 'undefined'. They should throw an error as I have never once declared them. But it's as if node.js has magically declared them and that is why they do not throw an error like the last one...Can someone explain?

There's a difference between undefined and "non-existent"
In the first two lines, global and req are existing variables, they just don't have the keys that you're asking for - so you get undefined.
However, blah simply doesn't exist - node has no place to even ask for the key you're looking for. Note that you can test for undefined as per this answer.
If you had defined blah above, but set no value to it (var blah;), you'd get another undefined error there instead.

global and req are existing variables.
Asking for a key in existing variable returns it, and if not found - tells that the key is undefined.
Next code will return undefined as well:
var blah = "";
console.log(blah.blah);

Related

Saving and getting an array in Localstorage?

I am trying to save an array into localstorage and then get it.
localStorage.setItem("savedquestionslist", questions);
console.log(localStorage.getItem(savedquestionslist));
The variable 'questions' is an array.
However I get this error:
ReferenceError: savedquestionslist is not defined.
I still get the error even if I do this:
localStorage.setItem("savedquestionslist", "test");
console.log(localStorage.getItem(savedquestionslist));
Does anyone know what the issue is? Thanks
savedquestionslist needs to be a string.
console.log(localStorage.getItem('savedquestionslist'));
The problem is in your syntax for getItem.
It takes in a string as an argument. You are passing a variable and the error represents that the variable savedquestionslist is not defined.
Change your code to :
localStorage.setItem("savedquestionslist", questions);
console.log(localStorage.getItem("savedquestionslist"));
An example would be
var questions = ['firstQuestion', 'secondQuestion', 'thirdQuestion'];
localStorage.setItem("savedquestionslist", questions);
console.log(localStorage.getItem("savedquestionslist"));
The error you're getting is because you forgot the quotes in the getItem call:
console.log(localStorage.getItem("savedquestionslist"));
// ------------------------------^------------------^
Or you can use literal access:
console.log(localStorage.savedquestionslist);
But in both cases, since local storage only stores strings, I'd use JSON, since otherwise your array won't be saved / retrieved correctly:
localStorage.setItem("savedquestionslist", JSON.stringify(questions));
console.log(JSON.parse(localStorage.getItem("savedquestionslist")) || []);
(The || [] is for if you've never set the item, it provides a default of an empty array.)

Error when Javascript 'or' || operator used in this case

So i have this situation basically
var a = someUndefinedVariable.name || "";
In this case why 'a' is not equal to an empty string???
This expression throws an error so I think execution just stops and Interpreter does not reaching to the part with the OR statement. Is it right?
However, without property name everything works fine.
Thanks a lot for attention.
Because someUndefinedVariable, being undefined, doesn't have the property name, so it crashes. Replace it with:
var a = (someUndefinedVariable && someUndefinedVariable.name) || "";
This expression throws an error so I think execution just stops and Interpreter does not reaching to the part with the OR statement. Is it right?
Yes. Exceptions halt execution (unless you catch them).
However, without property name everything works fine.
If a variable is not declared and you try to read from it, then you will get an exception: Uncaught ReferenceError: foo is not defined.
If a variable is declared, and has the undefined value, then you can access it freely. It is just undefined.
Trying to access a property of an undefined value throws an exception:
Uncaught TypeError: Cannot read property 'bar' of undefined
You are dealing with cases 2 and 3.
You might check someUndefinedVariable first, to prevent an access to a property of a undefined variable
var a = someUndefinedVariable && someUndefinedVariable.name || "";
you should use
var a = (someUndefinedVariable && someUndefinedVariable.name) || "";
since you are referring to a property of an undefined variable, it crashes, instead check if the variable exists before hand

Why does the console print undefined when I assign a variable?

Hey pretty simple task I am trying to do.... I'm trying to take the text in my textbox and assign it to a var. When I run without the var I am getting text but if I assign it to a var I get undefined. Could someone explain this to me as it is very confusing to me?
TL;DR: It does not.
You can see content of your variable test, il will output the same thing as before. In fact it is the variable assignement that returns the undefined you see here.
For instance:
var test = 'Hello' // => undefined
test // => 'Hello'
Another case is printing your variable with console.log. If you do so, the return value will be undefined but the output will be your variable content (Hello here).
console.log(test) // return: undefined / print: Hello
What's returning undefined is the statement itself that you entered into the console, NOT the value of var text.
To see that console.log(text) or simply type text in the console.

Deleting a subfield of a field that doesn't exist

I just observed the following weird behavior:
Deleting a variable that was not defined
> delete a
true
> delete a[0]
ReferenceError: a is not defined
> delete a.something
ReferenceError: a is not defined
> delete a.something[0]
ReferenceError: a is not defined
Deleting a subfield of a field that doesn't exist
> a = {}
{}
> delete a.foo
true
> delete a.bar.something
TypeError: Cannot convert null to object
> a.bar
undefined
I have two questions:
Why delete a works while a is not defined?
Why does deleting a.bar.something throw the error Cannot convert null to object instead of Cannot read property 'something' of undefined (because a.bar is undefined)?
According to documentation The delete operator removes a property from an object., so the answer for the first question would be that a is supposed to be a property of this object?
When using delete a; in c++ app, this error appears (and it's supposed to do) error: ‘a’ was not declared in this scope.
The answer is split into two. The first doesn't describe much but answer the question, while the latter goes into the nitty gritty details of the specification.
tl;dr
The first line works because in non-strict mode, trying to delete a variable just works.
The rest of the examples in the first section don't work because a isn't defined
delete a.foo works because there's no reason it shouldn't
delete a.bar.something throws because it's first trying to turn a.bar into an object before trying to access a.bar.something.
And now for something completely different
First, let's make clear that the two sections of code are conceptually different since the first talks about a variable which was not declared.
We'll be looking at how delete is specified quite a bit.
Let's start with the easier to understand parts:
> delete a[0]
ReferenceError: a is not defined
> delete a.something
ReferenceError: a is not defined
> delete a.something[0]
ReferenceError: a is not defined
All these lines are trying to do something with a, a variable which was not declared. Therefore, you get a ReferenceError. So far so good.
> delete a
true
This goes into the 3rd clause of the delete statement: a is an "unresolved reference", which is a fancy way of saying "it wasn't declared". Spec says to simply return true in that case.
> a = {}
{}
> delete a.foo
true
This one's intuitive as you expect (probably), but let's dive into it anyway. delete obj.property goes into the 4th clause:
Return the result of calling the [[Delete]] internal method on ToObject(GetBase(ref)) providing GetReferencedName(ref) and IsStrictReference(ref) as the arguments.
Welp that's a whole lot of uninteresting stuff. Let's just ignore everything after the [[Delete]] part, and just look at how [[Delete]] is specified. If I were to write it in js, it's be like this:
function Delete (obj, prop) {
var desc = Object.getOwnPropertyDescriptor(obj, prop);
if (!desc) {
return true;
}
if (desc.configurable) {
desc.magicallyRemove(prop);
return true;
}
throw new TypeError('trying to delete a non-configurable property, eh!?');
}
In the example, a does not have a property named foo, so nothing special happens.
Now it gets interesting:
> delete a.bar.something
TypeError: Cannot convert null to object
This happens because of some of the uninteresting things we ignored earlier:
Return the result of calling the [[Delete]] internal method on ToObject(GetBase(ref)) [...]
I highlighted the portion relevant to this specific snippet. Before we try to delete anything, spec tells us to call ToObject(GetBase(ref)), where ref = a.bar.something. Let's do that, then!
GetBase(a.bar.something) === a.bar
ToObject(a.bar) === ToObject(undefined) which throws a TypeError
Which explains the final behaviour.
Final note: The error message you've shown is misleading, since it says it tried to convert null into an object, which it didn't, as it tried to convert undefined into one. Latest chrome and firefox throw a more accurate one, but I think v8 only recently fixed the error message, so perhaps upgrading to node v11 will show a correct version.
I'm sharing experiments and readings, hope this will help!
1. Why delete a works while a is not defined?
If you try to read a property that isn’t there, JavaScript returns
“undefined”. This is convenient, but can mask errors if you’re not
careful, so watch out for typos!
Source: http://www.w3.org/wiki/Objects_in_JavaScript
"Delete" will remove both the value and the property, so as long as JavaScript returns a value for a, delete will work the same way that this example:
var a;
delete a;
Besides, as you said a is a property of this object. You can see this by testing this code:
> var a = {}
undefined
> a
{}
> this.a
{}
2. Why does deleting a.bar.something throw the error Cannot convert null to object instead of Cannot read property 'something' of undefined?
Please look at these examples:
NodeJS:
> var a = {}
undefined
> typeof a.b
'undefined'
> typeof a.b.c
TypeError: Cannot read property 'c' of undefined
at repl:1:12
at ......
> delete a.b.c
TypeError: Cannot convert null to object
at repl:1:10
at ......
Chrome console:
> var a ={}
undefined
> typeof a.b
"undefined"
> typeof a.b.c
Uncaught TypeError: Cannot read property 'c' of undefined VM335:2
> delete a.b.c
Uncaught TypeError: Cannot convert undefined or null to object
As you can see, both will manage a.b as an undefined value when testing typeof. But when deleting, chrome says that it may be undefined or null, while NodeJS consider this is a null value.
Would it be possible that NodeJS error is wrong formated?

Equivalent of Python's KeyError exception in JavaScript?

I am trying to access a certain member in a JavaScript object. In order to do this, I need to try out a couple of key values.
For example, Object['text/html'] which will give me an export link for a HTML document. However, not every object of this type will have a text/html key pair value.
In Python I would solve this problem using a Try-Catch block, with the KeyError exception. If I can do something similar in javascript, as in use an exception in a Try-Catch block, that would be great.
However, if alternatives exists instead of try catch blocks, that do achieve the same end goal, I would like to know about them as well.
EDIT:
I would prefer to use an exception over using functions. I do this because the text/html key might not be there, but it should be there. An exception seems more appropriate for this scenario
Javascript doesn't generate an exception when reading or writing a property that doesn't exist. When reading it, it just returns undefined. When writing it, it just creates the property.
You could create your own function that tests to see if the property exists and throws an exception if it does not (but you'd have to call that function whenever), but JS doesn't make an exception out of that on it's own like you are asking for.
If you want to test if a key exists on an object in javascript, you can use this construct with the in operator:
var obj = {};
var key = "test";
if (key in obj) {
// key exists
} else {
// key doesn't exist
}
If you try to read a key that doesn't exist, you will get undefined as the value.
var obj = {};
var value = obj.test;
alert(value === undefined);
The in operator does a better job of telling you whether the key exists that testing for undefined because undefined is a legal value for a key that exists.
In many cases, where you control the values that the keys have and a key that is present will never have a falsey value, you can also just check if the key has a truthy value:
var obj = {};
var obj.test = "hello";
if (obj.test) {
// key exists and has a truthy value
}
If you want to make sure that the object itself has the property and not any prototype that it is inheriting from, then you can do this:
var obj = {};
var obj.test = "hello";
if (obj.hasOwnProperty(test)) {
// key exists on the object itself (not only on the prototype)
}
Read this!
The accepted answer is correct however omits some points.
1) Accessing nested object
Like someone pointed out in the comment, Javascript returns undefined when the key doesn't exists in the object.
However, if you need to access an object inside an object (or an Array, or a function), well this break.
let a = {};
let userName = 'js'
let data = a.response[userName];
Cuz you will received actually a TypeError, basically because we are trying to read a property of undefined, which doesn't have any.
VM187:2 Uncaught TypeError: Cannot read properties of undefined (reading 'js')
at <anonymous>:2:22
2 Answering the question
The Python principle "Ask forgiveness not permission" - explain is actually for the most part working well in Javascript (and PHP, you didn't ask but well..). There are for sure some difference, or some situation where the difference is important, but for most use cases is the same
So this is how you would do it:
try {
let data = a.key1.key2['whatever'].nested.damn.object;
console.log(data)
} catch (error) {
let data = "noope";
console.log(data);
}
As you can see, in Javascript you don't really care about the error type, (for the most part, sure other situation you should case). Is almost like anything is in a Python's
try:
a = "hello" + 1 + {} + [] # crazy stuff here
except BaseException as bleh:
print(str(bleh))
Documentatin
MDN Working with objects
How do I check if an object has a key in JavaScript? [duplicate]

Categories