strict equality check for undefined - javascript

I cant seem to figure this answer out so maybe you could help shed some light. In my defense, undefined is a message returned when a variable, key, value etc could not be found. A message should be a string? No?
let foo = [{id: 1, you: "me"}]
let undif = foo.find(i => i.he === 1)
if (typeof undif === "undefined") {
console.log(undif) // not fired
}
if (typeof undif == undefined) {
console.log(undif) // not fired
}
if (typeof undif == 'undefined') {
console.log(undif) // fired!
}
Why cant I use typeof undif === 'undefined?

triple equals looks for both value and type;
hence undefined === 'undefined' will return false
for same reason your first case returns true
This is a wonderful article on double equals and triple equals along with falsy value comparsion

Your code had syntax errors (missing the opening braces after every if), but once those are fixed, the first and third are both fired.
let foo = [{id: 1, you: "me"}]
let undif = foo.find(i => i.he === 1)
if (typeof undif === "undefined") {
console.log('1', undif) // fired
}
if (typeof undif == undefined) {
console.log('2', undif) // not fired
}
if (typeof undif == 'undefined') {
console.log('3', undif) // fired!
}

Related

how to check a deeply nested object is undefined? [duplicate]

This question already has answers here:
How to avoid 'cannot read property of undefined' errors?
(18 answers)
How can I check for "undefined" in JavaScript? [duplicate]
(16 answers)
Closed 2 years ago.
I would like to check whether an object is undefined
this.state.data.value[0].name
I attempted the following
and these will say Type error this.state.data.value is undefined in the console.
if(typeof this.data.value[0].name=== "undefined"){
//do something
}
if(this.data.value[0].name == undefined){
//do something
}
if(!!this.data.value[0].name){
//do something
}
if(!this.data.value[0].name){
//do something
}
if(this.data){
if(this.data.value){ // It says type error, this.state.value is undefined in the console.
}
}
How shall I check the object this.state.value[0].name is undefined?
I attempted this
if (typeof (this.data) !== undefined) {
debugger;
if (typeof (this.data.value) !== undefined) {
debugger;
if (typeof (this.data.value[0].name != undefined)) {//cannot read value [0]
debugger;
}
}
}
My Solution, thanks to pranav-c-balan
if (this.data && this.data.value && this.data.value[0] && this.data.value[0].name) {
return true;
} else {
document.getElementById("myDIV").innerHTML =
"<b>Custom Error Text</b>";
return false;
}
A working Example
let data={};
data.value=[{name:123}];
function checkValue(){
if(data && data.value && data.value[0] && data.value[0].name){
return true;
}else{
return false;
}
}
let correct=checkValue();
if(correct){
console.log("This is valid, data.value[0].name Exist");
}else{
console.log("This is invalid,data.value[0].name do not Exist");
}
function checkValue2(){
if(data && data.value && data.value[0] && data.value[0].names){
return true;
}else{
return false;
}
}
let correct2=checkValue2();
if(correct2){
console.log("This is valid, data.value[0].names Exist");
}else{
console.log("This is invalid,data.value[0].names do not Exist");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.0/react-dom.min.js"></script>
You can check your object by using optional chaining (?.).
This will check every part of your chain. Say if it is undefined the data inside the state then it returns undefined excepts throwing an error.
let state = {
data: {
value: [
{name: 'value'}
]
}
}
console.log(typeof state?.data?.value?.[0]?.name);
console.log(typeof state?.data?.value?.[1]?.name);
console.log(typeof state?.datum?.value?.[0]?.name); // In this case it returns 'undefined' for dutum stage.
Note
Optional chaining has poor browser support until now. So you have to use Babel or any other Javascript compiler for browser support.
Just use the same typeof operator:
if(typeof(this.state) != 'undefined'){
if(typeof(this.state.value) != 'undefined') {
// next source
}
}

How to check for availability for a nested variable without checking all the preceding variable availability, in ReactNative?

For example, in iOS Swift, I can do something like this:
if (self.user?.company?.pic?.phoneNumber != null) { doSomething() }
Without the need to:
if (self.user != null && self.user!.company != null && self.user!.company!.pic != null && self.user!.company!.pic!.phoneNumber != null) { doSomething() }
In ReactNative (or Javascript), I found out that if an object is undefined, I can't check for the existence of the variable inside of it, so I have to check first whether the object is undefined or not, only then I can safely check whether the variable inside of it undefined or not.
if (typeof this.state.user !== "undefined" && typeof this.state.user.company !== "undefined" && typeof this.state.user.company.pic !== "undefined" && typeof this.state.user.company.pic.phoneNumber !== undefined) { this.doSomething() }
How can I turn this into just:
if (typeof this.state.user.company.pic.phoneNumber !== "undefined") { this.doSomething() }
or something similar?
Thanks.
Currently, optional chaining is a stage 3 draft, and so, you may be able to do it in the future.
EDIT:
Optional chaining will now be part of ES2020, and so you'll be able to do the following:
if (self.user?.company?.pic?.phoneNumber !== undefined) {
doSomething(); // phoneNumber exists
}
With that being said, it still has very limited browser support.
So, for the time being, you could instead create a function which recursively finds each object from a list of properties like so:
const optional_chain = (obj, [key, ...props]) =>
obj !== undefined && key ? optional_chain(obj[key], props) : obj;
const user = {
company: {
pic: {
phoneNumber: 1
}
}
}
console.log(optional_chain(user, ['company', 'pic', 'phoneNumber'])); // 1
console.log(optional_chain(user, ['company', 'pic', 'phoneNumber', 'x'])); // undefined
console.log(optional_chain(user, ['company', 'picture', 'phoneNumber'])); // undefined
console.log(optional_chain(user, ['x', 'picture', 'phoneNumber'])); // undefined
In your case, the usage would be as so:
if (optional_chain(self.user, ['company', 'pic', 'phoneNumber']) !== undefined) {
doSomething();
}
If you can’t use optional chaining which is still a proposal but available via babel plugin you could use a recursive utility function to test for the presence of each path segment:
const pluck = (item, path) => {
const [, part, rest] = /^([^.]+)\.*(.*)/.exec(path) || [];
if (!part) {
return null;
}
const o = (item || {})[part];
if (o == null) {
return null;
}
return rest.length ? pluck(o, rest) : o;
};
if (pluck(this.state, ‘user.company.pic.phoneNumber’)) {
doSomething();
}

How to avoid assigning a variable in an if

Given the following snippet:
let a;
if (obj === undefined ||
obj.prop === undefined ||
(a = await getResultFromLongOperation(obj.prop)) === undefined) {
// Do things to handle the case where the params were wrong and throw an error
}
console.log(a); // a is not undefined
I would like to avoid assigning the value of a inside the if.
But I also don't want to make multiple calls to getResultFromLongOperation and I don't want to duplicate the "things to handle the case where the params where wrong".
How can I refactor this?
Only solution I found was to refactor as such:
function doThingsToHandleTheCaseTheParamsAreWrong() {
// Do things to handle the case where the params were wrong and throw an error
}
if (obj === undefined ||
obj.prop === undefined) {
doThingsToHandleTheCaseTheParamsAreWrong();
}
let a = getResultFromLongOperation(obj.prop);
if (a === undefined) {
doThingsToHandleTheCaseTheParamsAreWrong();
}
console.log(a); // a is not undefined
Is this really better?
Would this construct work in your case:
const a = getResultFromLongOperation(obj.prop) || doThingsToHandleTheCaseTheParamsAreWrong();
Depending on if a can return other falsy values that undefined.
const tmpA = getResultFromLongOperation(obj.prop);
const a = tmpA !== undefined ? tempA : doThingsToHandleTheCaseTheParamsAreWrong();

Javascript "deep" check for defined

I could swear that once upon a time, I came across some code that used some js library (maybe lodash??) to do a "deep" check for whether something is defined.
Example:
someLib.isDefined(anObject.aNestedObject.anotherNestedObject);
(would return true if anotherNestedObject is defined, but would return false (and not throw an exception) if anObject or aNestedObject were undefined.
Did I totally dream that, or is there some well-known function out there that does that?
As I wrote in my comment I don't think that it's possible.
The expression anObject.aNestedObject.anotherNestedObject is evaluated before the someLib.isDefined function is invoked so an exception will be thrown (if anObject or aNestedObject don't exist) before the function had a chance to do anything.
Maybe if you'd pass it as a string: someLib.isDefined("anObject.aNestedObject.anotherNestedObjec‌​t")
But, it's easy to check that like this:
if (anObject && anObject.aNestedObject && anObject.aNestedObject.anotherNestedObject) {
...
}
Or just implement your own function, it's pretty simple:
function exists(obj: any, keys: string | string[]) {
if (typeof keys === "string") {
keys = keys.split(".");
}
return keys.every(key => {
if (!obj) {
return false;
}
obj = obj[key];
return true;
});
}
(code in playground)
Lodash's has():
_.has(object, path)
Example:
var object = {a: {b: 'test', c: 'test2'}};
_.has(object, 'a.b');
// => true
_.has(object, 'a.d');
// => false
Full documentation
Source code for _.has()
No there is no well-known function to do this, but you can check it safely in this way:
if (typeof anObject != "undefined"
&& typeof anObject.aNestedObject != "undefined"
&& typeof anObject.aNestedObject.anotherNestedObject != "undefined") {
console.log("defined");
}else{
console.log("undefined");
}

Getting strange error when running the following function

I am trying to do something like
HTML('slider1') = someimage;
But my HTML() function is not returning document.getElementById('slider1');
function HTML(id){
if(typeof value !== undefined){
return document.getElementById(id).innerHTML;
}
}
typeof allows the identifier to never have been declared before.
function HTML(id){
if(typeof value == "undefined")
{
//do nothing
}else{
return document.getElementById(id).innerHTML;
}
}
You can also try
if(typeof neverDeclared === typeof undefined) //also no errors and no strings
I think you are trying to assign some image through innerHTML, you may update your function to something like this
function HTML(id){
if(typeof value !== undefined){
return document.getElementById(id);
}
}
HTML('slider1').innerHTML = someimage;
//OR
function HTML(id, htmlChunk){
if(typeof value !== undefined){
document.getElementById(id).innerHTML = htmlChunk;
}
}
HTML('slider1',someimage);

Categories