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)
) ?? [];
Related
I am trying to find whether my cart is empty by using const isEmpty = !cart.line_items.length;, but it is returning Cannot read property length of undefined. So i console.logged whether cart.line_items is an array and it ends up returning false, true, true. So for some reason it isnt recognized as an array at the start. How would I fix this?
Adding this catch if(!cart.line_items) return 'Loading...' seemed to solve the problem
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.
So, I have two ajax calls, which are chained in a promise.
For example
promiseData.then(res1, res2) {
let responseOneParsed = JSON.parse(res1)
let responseTwoParsed = JSON.parse(res2)
}
I am concatenating these two, like this
concatenatedArr = responseOneParsed.data.concat(responseTwoParse.data)
So, this is clear.
But, sometimes one of these two ajax calls returns undefined, since the response is empty (should be), and I get the error:
error TypeError: Cannot read property 'concat' of undefined
Which is again very clear, but how can I scale this code to accept one of these parameters, if other is undefined, so it does not fail? Is .concat() used wrongly here?
You can easily make it with || operator and empty array: []
like this
concatenatedArr = (responseOneParsed.data || []).concat(responseTwoParse.data || [])
Isn't this just a case of proper sanity checking?
Check to see if responseOneParsed.data is valid, if it is, call concat, else, apply the second data.
concatenatedArr = responseOneParsed.data ?
responseOneParsed.data.concat(responseTwoParse.data ? responseTwoParse.data: [] )
:responseTwoParse.data
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
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.