Cannot read property 'length' of undefined react - javascript

TypeError: Cannot read property 'length' of undefined
That's what the compiler says when I run my react app. What I do need to do with this?
request = (start,end) => {
if(this.state.teams.length < 1){
axios.get(`${ URL }/teams`)
.then( response => {
this.setState({
teams:response.data
})
})
}
axios.get(`${ URL }/articles?_start=${start}&_end=${end}`)
.then( response => {
this.setState({
items:[...this.state.items,...response.data]
})
})
}

I would suggest to check first if the props is undefined or empty or even declared.
for example:-
const card = props && props.cards && props.cards.length > 0 ?
props.cards.map((card, i) => {
return (
<card >
)
}) : '';
And return your card.

I would suggest using a check to see if "teams" is undefined before trying to get the length.
if (value === undefined) {
// value is undefined
}

Be sure that the teams value of your component's state is initialized with an array value like this :
class MyComponent extends React.Component {
state: {
teams: [],
};
}

Probably because you're having a variable that is supposed to contain an array but is undefined when referencing the length property. Try searching for .length in your editor and create an empty array if it's not initialized:
if ((arr || []).length > 0) {
// do something
}
// or
if (arr?.length > 0) {
// do something
}

Related

"TypeError": Cannot read properties of undefined in Vuejs?

It works like this: I have a table made in Vue, where I have some select options. This error appears when I have a grupo (group) and this group is not associated with a maquina (machine), what shouldn't happen, the objective is that only "-" appears. Throws an error in the console and does not show in my DataTable.
The error: [/Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'id_area')
This is the part of my code that I believe is causing this error:
computed: {
linhas () {
return this.lista.map(row => {
const group = this.grupos.find(g => g.id === row.id_grupo);
const machine = this.maquinas.find(m => m.id === group.id_maquina);
const area = this.areas.find(a => a.id === machine.id_area);
return ({
href: {path: this.editRoute + row.id},
cols: [
row.id,
row.tag,
row.descricao,
row.tipo === "ANALOGICA" ? "Analógica" : "Digital",
group.nome,
(machine || { nome: "-" }).nome,
(area || { nome: "-" }).nome
]
});
});
}
},
Can someone help me? I do not understand why this happening.
The array.find() method returns undefined if the value is not found (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find).
So if ther is no "machina" with the id group.id_maquina retrieve from the previous line, the line const machine = this.maquinas.find(m => m.id === group.id_maquina); set value undefined to the machine const.
And here's your error happens: reading id_area from machine that is undefined.
So you have to check if your variables are not undefined after array.find()
//...
const group = this.grupos.find(g => g.id === row.id_grupo);
if (group) {
const machine = this.maquinas.find(m => m.id === group.id_maquina);
if (machine) {
const area = this.areas.find(a => a.id === machine.id_area);
}
}
//...

Settings.js:168 Uncaught TypeError: Cannot destructure property 'component' of 'templates.find(...)' as it is undefined

Hi guys I am struggling to solve this error, here is my code
import TemplateOne from "./Template_1";
..........
const templates = [
{
title: "TemplateOne",
component: TemplateOne,
}
]
const { component: SelectedComponent, title } =
templates.find(function (Component,idx){
if (Component.id === templatesID.stid) {
return true;
}
return false;
});
And I am displaying the selected component like this :
<SelectedComponent />
Note I have multiple templates
What is wrong here?
The find returns undefined if no element is found that match the provided testing function.
So you could save the result of find in a variable, check if is truthy and then destructure it.
The returned value for find can be undefined, so you can't desctructre the result directly, just try this:
const currentTemplate = templates.find(function (Component,idx){
if (Component.id === templatesID.stid) {
return true;
}
return false;
});
and when you display the component
currentTemplate ? <currentTemplate.component /> : null

Checking if !isLoading and state exists with useTracker meteor subscribe and findOne mongo

I normally can do this when I render the react component with an isLoading however if I try to use that to test that a variable is ready it complains that the map is undefined even though in the console it certainly is an array value that I am selecting. The isLoading returns undefined sometimes, and I've tried checking for if isLoading is !undefined and so here I am stuck.
const { leadsBuilder, isLoading } = useTracker(() => {
const noDataAvailable = { leadsBuilder: [] };
if (!Meteor.user()) {
return noDataAvailable;
}
const handler = Meteor.subscribe("leadsBuilder");
if (!handler.ready()) {
return { ...noDataAvailable, isLoading: true };
}
const leadsBuilder = LeadsBuilderCollection.findOne({ _id: params._id });
return { leadsBuilder };
});
if (!isLoading && leadsBuilder) {
let stateReplace = [];
leadsBuilder.inputs.map((leadInput, i) => {
stateReplace.push({ id: i, text: leadInput.name });
});
}
You're testing if leadsBuilder is truthy, but your invoking the .map on a property of leadsBuilder.
You should replace your condition by:
if(!isLoading && leadsBuilder?.inputs?.length) {
//your code
}
The ? test if the variable / property is defined, and then we use length because we want the array to not be empty

obj is undefined sometimes and works perfectly other times

In the computed propertys I am trying to match an ID received from an API to an array of objects with ID keys also received from an API and retrieve the name key from the matching ID object.
the obj variable occasionally throws an "obj is undefined" error but not consistently.
I think its to do with the IDs been async. Changed the function from arrow to classic function to not mess with the this scope.
data() {
return {
upComing: [],
popular: [],
topRated: [],
playingNow: [],
details: [],
genres: []
}
},
computed: {
genre: function() {
let list = this.upComing[0] ? this.upComing[0].genre_ids[0] : 0
let obj = this.genres.find(function(o) {
return o.id === list
})
return obj.name
}
},
created() {
let self = this
APIService.getUpcoming()
.then(response => {
self.upComing = response.data.results
//console.log(this.upComing)
})
.catch(error => {
console.log(`There was an error: ${error.response}`)
}),
APIService.getGenres()
.then(response => {
this.genres = response.data.genres
//console.log(this.genres)
})
.catch(error => {
console.log(`There was an error: ${error.response}`)
})
}
}
I get this TypeError: "obj is undefined" and this [Vue warn]: Error in render: "TypeError: obj is undefined"
and it throws them each twice. So i have 4 errors in the console but its just these 2 twice with a 1 second delay.
The error is that this.genres is [], so the computed property is computed when your component is mounted, so the result of this.genres.find(.... is undefined (because it can't find something in an empty list).
You can have a default value by using the || notation like this:
let obj = this.genres.find(function(o) {
return o.id === list
}) || { name: 'defaultName'}
This means that if nothing is found on the genres list, you still have a default result, then you can return obj.name with out having the error.
Also note that the genres variable is empty because the computed method is tun before your promise is resolved, and it runs again after you update that variable
You're most likely right about the issue being the async stuff, couldn't you just safeguard against undefined by doing something like this:
computed: {
genre: function() {
let list = this.upComing[0] ? this.upComing[0].genre_ids[0] : 0
let obj = this.genres.find(function(o) {
return o.id === list
})
return obj ? obj.name : '' // or whatever should be the default
}
},

get value from a filtered array of objects

I have an array of objects each object contains a name property and a value property
what I want to do is return the value for the specified name
I am using a computed property
computed: {
statAlertCount() {
var stat = this.siteStatistics.filter(item => {
console.log(item);
return item.name == "site_alert_count";
});
console.log(stat[0]);
}
}
this code returns and object 'stat' which i can console out. it looks like this.
but if I try to access the value using stat[0].stat then I get the following error
app.js?id=f37d3d495892e39c6054:85474 [Vue warn]: Error in render: "TypeError: Cannot read property 'stat' of undefined"
I think you just need to return:
computed: {
statAlertCount() {
var stat = this.siteStatistics.filter(item => item.name === "site_alert_count");
return stat.length > 0 ? stat[0].stat : '';
}
}
An alternative solution using find:
computed: {
statAlertCount() {
const statItem = this.siteStatistics.find(item => item.name == "site_alert_count");
return statItem ? statItem.stat : "";
}
}

Categories