Cannot read property 'includes' of undefined - javascript

I am new to JavaScript, am I was trying to dissect an embedded message. Here's my code, it runs fine for a few mins, works accordingly but idk what goes wrong.
bot.on('message', (message) => {
for (var i = 0; i < message.embeds.length; i++) {
if (message.embeds[i].title.includes("text!")) {
message.channel.send('reply')
}
}
})

Its because there is at least one item inside the embeds array items that missing the title property.
You will need to update the if statement to be:
If (message.embeds[i] &&
message.embeds[i].title && ...)

I think this code can fix this problem.
bot.on('message', (message) => {
for (var i = 0; i < message.embeds.length; i++) {
if (message.embeds[i] && message.embeds[i].title.includes("text!")) {
message.channel.send('reply')
}
}
})

It means inside message.embeds[i] there is at least one element without title property.
You should check first if message.embeds[i].title exists and perform other operations after the check.

You can write your code more defensive like this. Instead of
if(message.embeds[i].title.includes("text!"))
you can write the following
if(typeof message.embeds[i].title === "string" &&
message.embeds[i].title.includes("text!"))

Probably some of the embed object is coming without the title property.
You can safely use your logic changing your if condition to:
if ('title' in message.embeds[i] && message.embeds[i].title.includes("text!")) {
/* ... */
}

JavaScript is not a type safe language, and the error is caused by not being type safe. We will have to check if object exists and nested properties exists and after we should be able check the value. In your case:
bot.on('message', (message) => {
// check if main obj and main property exist
if (message && message.embeds) {
for (var i = 0; i < message.embeds.length; i++) {
// now, check if title exists and after check the text inside
if (
message.embeds[i].title &&
message.embeds[i].title.includes("text!"))
{
message.channel.send('reply')
}
}
}
});

its null pointer error. some of your object parameter is null but its mapped in html. Please try to add more null checks to avoid this .
always check an item before accessing it
bot.on('message', (message) => {
for (var i = 0; i < message.embeds.length; i++) {
if (message.embeds[i].title && message.embeds[i].title.includes("text!")) {
message.channel.send('reply')
}
}
})

Related

how to compare all the keys of object in js?

I need to compare all the selected attribute with variants on the AliExpress site.But my code is checking for only first key and adding class but when its come to 2nd and 3rd class its look like its not checking for them.I tried using length property but it says length is undefined.
function selectAttributes() {
chrome.storage.local.get(null, function(result) {
for (i = 0; i < result.ae_items.length; i++) {
console.log(result.ae_items[i].attributes);
for (var key in result.ae_items[i].attributes) {
$(".sku-property-list").each(function() {
$(".sku-property-item").each(function() {
if ($(this).has("img")) {
var title = $(this).children(".sku-property-image").children("img").attr("title");
if (title == result.ae_items[i].attributes[key]) {
$(this).addClass("selected");
}
} else {
var title = $(this).children(".sku-property-text").children("span").text();
alert(title);
}
});
});
}
}
});
}
This is comparing all the keys of object but the issue was with else block. Else block was not executing so I tried different ways and finally came out with decision that no need to use else block. Its working after removing else block

Cannot read property 'length' of undefined despite check for undefined

I'm writing some code to generate JSX based on items in an array, however I'm getting the error 'Cannot read property 'length' of undefined' despite having checks in place to see whether the variable is actually undefined. The code is really long so I've summarised the problem here:
render() {
var metadata = this.props.data["metadata"]
if(typeof metadata !== undefined && metadata.length !== undefined) {
for(var i=0; i<metadata.length; i++) {
console.log(metadata[i]);
}
}
}
The render method is inside a component, which is placed inside another, by doing
<Marksheet data={this.state.data} />
I've checked to make sure that data is actually defined and being supplied as a prop, but even if it was undefined, I don't understand why it's saying cannot read property length of undefined.
You could also use the Array.isArray method:
render() {
var metadata = this.props.data["metadata"];
if(Array.isArray(metadata)) {
metadata.forEach(val => console.log(val));
}
}
The string "undefined" is not the same as undefined.
Try changing your code to the following:
render() {
var metadata = this.props.data["metadata"]
if(metadata !== undefined && metadata.length !== undefined) {
for(var i=0; i<metadata.length; i++) {
console.log(metadata[i]);
}
}
}
That basically checks to ensure both metadata and metadata.length are not equal to undefined before running that for loop.
Or just simply. You might also check for metadata.length >0 (instead of just length)
render() {
var metadata = this.props.data["metadata"]
if(metadata && metadata.length) {
for(var i=0; i<metadata.length; i++) {
console.log(metadata[i]);
}
}
}

JavaScript API Response - Check if variable exists

In an API response, I want to check if a variable exists. If it doesn't, I want to assign it a blank value:
if(!data3.fields[i+2].values.value[0]) {
data3.fields[i+2].values.value[0] = "";
} else {
break;
}
Error in the console is:
Uncaught TypeError: Cannot read property 'value' of undefined
This confuses me because I thought that's exactly what my if the statement was checking. Any ideas what's going on here?
The if check won't protect you from trying to use an undefined variable. In your instance the values property is undefined. If you wanted to test for that you would need to first check that specific property
if(data3.fields[i+2].values !== undefined && data3.fields[i+2].values.value[0]){
//do something with data3.fields[i+2].values.value[0]
}
additionally, if you are in a scenario where you don't even know if data3 exists (for example you are checking for the existence of a third party script, or something else in your environment) you would need to use the typeof operator to be safe. E.G.
if(typeof(ga) !== 'undefined'){ //typeof returns a string. This would be testing for google analytics on a page.
It doesnt work like PHP does (which checks the whole 'chain'). In your example, you actually check if .value[0] of values exists, but dont check if values exists. The full version should be:
if( data3 && && data3.fields[i+2] && data3.fields[i+2].values && !data3.fields[i+2].values.value[0]) {}
In your code ata3.fields[i+2].values is undefined, and you're trying to access value[0] of 'undefined'
Or slightly more simplefied, if you wand to test if d has a value, you have to make sure that a, b and c aldo have a value:
if( a && a.b && a.b.c && !a.b.c.d){ /* ... */ }
You can remove checks on the left side of the checks if you are sure those exist. E.g.: If you know that a.b always exist, you can simplefy:
if( a.b.c && !a.b.c.d){ /* ... */ }
If you really want to make sure the complete property chain is not undefined you have to check every single step and the later ones won't be executed if at least && condition is false.
if (data3 && data3.fields && data3.fields[i+2] && data3.fields[i+2].values && data3.fields[i+2].values.value && data3.fields[i + 2].values.value[0]) {
data3.fields[i + 2].values.value[0] = "";
} else {
break;
}
Another way would be to just do it and catch the exception:
try {
data3.fields[i + 2].values.value[0] = "";
} catch (e) {
break;
}
The error is telling you that data3.fields[i+2].values is undefined. You can't check for a property .value on undefined.
You'd need to verify each property/index belongs along the way if you always want that nested path to default to an empty string.
if (data3.fields[i+2] === undefined) {
data.fields[i+2] = {};
}
if (data3.fields[i+2].values === undefined) {
data3.fields[i+2].values = {};
}
if (data3.fields[i+2].values.value === undefined) {
data3.fields[i+2].values.value = [];
}
// and finally your empty string assignment
if (data3.fields[i+2].values.value[0] === undefined) {
data3.fields[i+2].values.value[0] = '';
}
Depending on your requirements, you might be able to get away with assigning a stub as soon as you know data3.fields[i+2] is undefined.
if (data3.fields[i+2] === undefined) {
data3.fields[i+2] = {
values: {
value: ['']
}
};
}

Possible to ignore Cannot read property '0' of undefined? [duplicate]

This question already has answers here:
How to avoid 'cannot read property of undefined' errors?
(18 answers)
Closed 2 years ago.
I am creating a personal script that in some instances gets the error:
Cannot read property '0' of undefined
I have something like this
item["OfferSummary"][0]["LowestUsedPrice"][0]["FormattedPrice"]
Is it possible to completely ignore/override this error so that it just prints n/a or -- in that scenario?
You can use try and catch to perform error handling.
You can use a boilerplate function to do so:
function get(obj, property) {
if (Array.isArray(property)) {
var current = obj;
for (var i = 0, l = property.length; i < l; ++i) {
if (Object(current) === current) current = current[property[i]];
else {
current = undefined;
break;
}
}
return current;
}
if (Object(obj) === obj) return obj[property];
}
Pass either a string or an array to get to find the property -- if not found, undefined will be returned.
Example:
get(window, ['location', 'href']); // "http://stackoverflow.com..."
get(Number, 'MAX_VALUE'); // 1.7976931348623157e+308
Even if you can use try and catch I wouldn't do that, I prefer avoid errors at all, so you'd just need to check the object you're reading:
if(item && item["OfferSummary"].length && item["OfferSummary"][0]["LowestUsedPrice"].length) {
//then do whatever
}
if you know that item is always defined you can avoid to check it in the if.
Similar to Qantas' answer, but using an in test. Always expects the property list to be an array, I can't see the point of using this to get a single property so no concession for that case:
function get2(obj, prop) {
for (var i=0, iLen=prop.length - 1; i<iLen; i++) {
if (typeof obj[prop[i]] == 'object') {
obj = obj[prop[i]];
} else {
// Property not found, return undefined (or other suitable value)
return;
}
}
return obj[prop[i]];
}
var foo = {foo:{bar:{meh:'meh!'}}};
var fum = {meh:'meh!'};
console.log(get2(foo,['foo','bar','meh'])); // meh!
console.log(get2(fum,['meh'])); // meh!
console.log(get2(Number,['MAX_VALUE'])); // 1.7976931348623157e+308
console.log(get2(Object,['prototype','toString'])); // function toString() { ... }
Edit
Per Qantas' comment, the test has been updated.

how to check in an array whether it has a key:value or not?

var people =[{title:'Alan', hasChild:true},
{title:'Alice', hasDetail:true},
{title:'Amos', header'A'},
{title:'Alonzo'},
{title:'Brad'},
{title:'Brent'},
{title:'Billy'},
{title:'Brenda'},
{title:'Callie'},
{title:'Cassie'},
{title:'Chris'}];
I want to check in this array, whether it contains a key,value header:value in it or not. I want to check this for each elements.
This should do it:
for (var i = 0, c = people.length;i < c;i++) {
if (people[i].header) {
// yay
// not sure wether you want to check the value as well
// but if that is the case, you'd do this
if (people[i].header == 'A') {
// do some more stuff
}
} else {
// nay
}
}
for(var i = 0; i < array.length; ++i){
if(array[i]["header"])
//Do stuff with the header
else
//Do stuff without it
}
This should work... Though you've got an error in the element with the header - it should be header:'A', with the :
you can check if it is defined or not using typeof
for (var i in arr) {
if (typeof arr[i].header !== 'undefined') {
//key present
} else {
//key not present
}
}

Categories

Resources