How to solve cannot read property "length"? [reactjs] - javascript

I am trying to get the length of an object but am getting this error message:
Uncaught TypeError: Cannot read property 'length' of undefined
I am trying to get the length and getting a popup when the length is zero.
I tried using this.props.storyboardTargets.length === 0
case 1: data not available so (!this.props.storyboardTargets)--> undefined
case 2: data was there and later deletd or cleared so need to check the length
Here is my code below:
handleShowPopupTarget = () => {
if (this.props.storyboardTargets && !this.props.storyboardTargets.length) {
console.log(this.props.storyboardTargets);
toastWarning(WARNING_MSG_NO_TARGET);
}
};

The way you have it written now does not handle the issue that this.props.storyboardTargets may be undefined. You need to update it like so:
handleShowPopupTarget = () => {
if (!this.props.storyboardTargets || !this.props.storyboardTargets.length) {
console.log(this.props.storyboardTargets);
toastWarning(WARNING_MSG_NO_TARGET);
}
};
This means if storyboardTargets is undefined, or its length is 0, toastWarning will fire.
As an alternative, you could define a default prop for your component of an empty array for storyboardTargets. That way it would never be undefined.

The error message means that storyboardTargets in undefined. Try seeing if storyboardTargets is being passed in to the component that contains your handleShowPopupTarget method.

use lodash's get, it simplifies a lot those kind of buggy checks:
_.get(this.props, 'storyboardTargets.length', 'default'); // you could use 0 instead of 'default' in your case

Your original code was
if (!this.props.storyboardTargets.length) {
And it fails because this.props.storyboardTargets is undefined and well you can not read properties of something that is undefined so it throws an error.
So after that you listened to advice and changed your code to be
if (this.props.storyboardTargets && !this.props.storyboardTargets.length)
So now this stops the undefined error from happening on this line because the truthy check on this.props.storyboardTargets prevents the evaluation of the second half of the code. So that means the code will not go into the if. but you WANT it to go into the if statement if it is not defined.
So what you need to do is change it to be an OR check so if it is NOT defined OR it does not have a length
if (!this.props.storyboardTargets || !this.props.storyboardTargets.length)
Now it goes into the if statement id it is undefined and will not throw the error.
The other solution is to see that it is undefined and set it to a default value
this.props.storyboardTargets = this.props.storyboardTargets || []
if (!this.props.storyboardTargets.length)
Now if the array is undefined, it sets it to an empty array and the if check will work correctly. Changing the data might not be the best solution if other things rely on undefined.

Related

Cannot read property 'push' of undefined in empty array

Trying to get rid of the error TypeError: Cannot read property 'push' of undefined. I have this snippet causing the issue:
const parent_lead_contact = this.props.parentLeads?.filter((lead) =>
lead.contact_guid.includes(this.props.parent_lead_party_guid)
);// This is an array which can be empty
if (parent_lead_contact?.length > 0) {
parent_lead_contact[0].is_parent_lead_contact = true;
} else {
parent_lead_contact.push({ is_parent_lead_contact: true }); // TypeError: Cannot read property 'push' of undefined
}
Is there a proper way to get this? I am filtering data from a selector. Sometimes, the result would be an empty array. The important thing is that the selector is not returning is_parent_lead_contact property, but I have to add this property to the array regardless the array is empty.
Thanks a lot for spotting the issue.
If an optional chain fails, everything past the ?. is ignored, and the expression evaluates to undefined. So this line
const parent_lead_contact = this.props.parentLeads?.filter((lead) =>
lead.contact_guid.includes(this.props.parent_lead_party_guid)
);// This is an array which can be empty
will not produce an array that might be empty - rather, it'll produce either an array that's been filtered, or undefined. That line should be changed to
const parent_lead_contact = this.props.parentLeads?.filter((lead) =>
lead.contact_guid.includes(this.props.parent_lead_party_guid)
) ?? [];

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

Split not working in javascript ,Uncaught TypeError

Can someone explain me why if condition in this code isn't working?
var zaposleni=[];
for(i=1;i<brOpcija;i++){
zaposleni.push(myOpts[i].value);
}
var zaposleniRestoran=[];
for(i=1;i<brOpcija;i++){
if(zaposleni[i].split(' ').slice(2).join(' ') == vrednostSelekta()){
zaposleniRestoran.push(zaposleni[i].split(' ').slice(0,2));
}
}
Here,i have array zaposleni where i push some values,and array is look like ["name" "surname" "restaurantName"],and then i am checking if restaurantName == vrednostSelekta() (where vrednostSelekta() is return value of some function in javascript),but i always get this error:
Uncaught TypeError: Cannot read property 'split' of undefined
at HTMLSelectElement.<anonymous> (zaposleni.js:51)
at HTMLSelectElement.handle (jquery.min.js:55)
at HTMLSelectElement.o (jquery.min.js:49)
But when i erase this if,and then type that in debugger,i get no error and it is working there..Thanks in advance!
Looks like the "zaposleni" array is empty or maybe there is only one element in it. Your for loop is starting at "i=1".
In the error, Cannot read property 'split' of undefined means that you're calling .split(...) to something that isn't defined.
This means that at the beginning of the if, the script is stopping when zaposleni[i] is not defined.
This is probably because i is bigger than the length of zaposleni at the biggest value for i, as you're iterating up to the same value, but you're starting to push at i=1 rather than i=0, as array indices in JS start at 0. In other words, you're adding a value at zaposleni[0], not zaposleni[last index value], and requiring from zaposleni[1] up to zaposleni[last index value], so the last one will be undefined.
The issue may also be that myOpts[i].value is probably undefined for some values of i, so I would recommend checking that

Why does reading a property sometimes throw an error in javascript?

Suppose I have some variables:
var s = 's', i = 0, o = {}, a = [], n = null, nan = NaN, u;
How can I make any sense of when reading x.p will return undefined, and when it will throw a TypeError?
s.p; // undefined
i.p; // undefined
o.p; // undefined
a.p; // undefined
n.p; // TypeError!
nan.p; // undefined
u.p; // TypeError!
P.S. Are null and undefined the only weird values in this way? Are there others?
Edit
I'm aware that by declaring variables as I have, several of my values have been automatically wrapped by objects (e.g. Number), despite being primitives. Therefore I can treat them like "proper" objects (e.g. {}, []) and attempt to read their properties. But I can't find much explaining what is and isn't wrapped this way.
Yes, null and undefined are the only values that throw an exception when being used in a property access. The dot and bracket property accessors do invoke the internal CheckObjectCoercible function, which is defined as following:
The abstract operation CheckObjectCoercible throws an error if its
argument is a value that cannot be converted to an Object using
ToObject. It is defined by Table 15:
Table 15 — CheckObjectCoercible Results
Argument Type | Result
--------------+------------------
Undefined | Throw a TypeError exception.
Null | Throw a TypeError exception.
Boolean | Return
Number | Return
String | Return
Object | Return
null and undefined being the values that represent Nothing cannot be converted to objects ("wrapped" as you say). Notice that you could of course have an object with an existing property that throws on access, like
var o = {get p() { throw new TypeError("you may not access this"); }};
o.p // TypeError
When you're reading the property of something that's undefined. You're basing saying:
What is undefined of undefined? or in the case of null what is undefined of null ? Neither undefined nor null are objects, therefore you can't set or get properties on/from them. With that in mind, an error will be thrown.
When the object is null/undefined, it'll throw an error because it'll try to access a property of an object that does not exist in first place.
On the other cases, it'll try to access a property of an existing object and will return undefined because the property is not found.
Please note that almost everything in js is an object, as you can see here.
let's firstly start with
why undefined on:
var s='s';
You assigned s to string which is primitive type. Javascript is tricky here in one sense. Though primitive type, when you try to access the property by doing:
s.p
It firstly does this internally:
String(s)
and creates the object and then tries to see if it has that property which is, of course not defined and thus you get undefined. Almost similar things happen with numerical assignment and NAN.
For n=null:
If you do:
var n=null;
typeof n;//"object"
n.p// throws typeerror
In fact,null can be thought of special kind of object without any properties or method to represent absence of value and thus, you get typeerror when you try to access any properties of null.
a.p
o.p
Easily, you can see that you are trying to access the property of an object than is not defined or not built-in and thus it should say, undefined. You should be surprised to see other than that :D.
To add to the other answers here, there is an easy way to check if a property access will throw an exception. Simply loosely compare the value you're unsure of to null, like so:
if(x != null) { // note the LOOSE equality, rather than !==
// do something with x.prop
}
The reason this works is that only null and undefined * throw errors on property access, and they are only loosely equal to each other. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_when_to_use_them.
* There is also a case where some JS objects can apparently "emulate" being undefined, in which case they also are loosely equal to null and undefined.

Comparison to -1 or undefined don t work, either with == or ===

Here a sample of code:
do
{
line=gets(smil);
if (line===-1){console.log("Abort");callback(-1);}
console.log("line= "+line);
}while(line.search("<video")===-1);
The first output goes well, but suddenly, I get
line= -1
TypeError: Object -1 has no method 'search'
gets is a custom function, wich return either a string or -1 in case of error.
I tried with == instead of ===, but it just do the same.
I tried to replace the return -1 of gets by undefined, but I just get
line= undefined
TypeError: Cannot call method 'search' of undefined
instead.
Why the if don t execute?
EDIT:
Tried with
var pline
do
{
pline=gets(smil);
if (pline===-1){console.log("Abort");callback(-1);}
console.log("line= "+pline);
}while(pline.search("<video")===-1);
to avoid overriding another variable, got the same result
It's a two-fer this question.
1st - You're overwriting the variable line right after the do.
That's why you're getting Uncaught TypeError: Object -1 has no method 'search'
Change that line to parsed_line = gets(smil); //also never forget semicolons
2nd - search isn't a function of String, you want the indexOf() function.
So change while(line.search()) to while(line.indexOf()).
I made a fiddle for you that demonstrates it here
try adding a break.
do
{
line=gets(smil);
if (line===-1){
console.log("Abort");
callback(-1);
break;
}
console.log("line= "+line);
}while(line.search("<video")===-1);

Categories