Console Error: Unhandled error during execution of mounted hook Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'split')
It seems to work up until it comes across a group that has no data for continent.
This looks like the issue to me but I'm not sure how to solve it.
Also I would like if possible to remove duplicates and the end comma for all fileds in the JSO. Is there a better way to do this as one function?
Any help is greatly appreciated
JSON
"response": [
{
"group": {
"continent": "ASIA,EUROPE,ASIA,EUROPE,ASIA,ASIA,EUROPE,EUROPE,ASIA,AUSTRALASIA,AUSTRALASIA,EUROPE,",
"location": "AS,AS,AS,AS,EU,AF,EU,AF,AU,AU,AU,AU,",
},
},
{
"group": {
"continent": "ASIA,EUROPE,AFRICA,EUROPE,ASIA,AFRICA,EUROPE,",
"location": "AS,AS,AS,AU,AU,",
},
},
{
"group": {
"continent": "ASIA,",
},
},
{
"group": {
"continent": "EUROPE,",
},
},
{
"group": {
"continent": "ASIA,EUROPE,",
"location": "AU,AU,"
},
},
....
]
methods: {
removeDuplicates() {
const uniques = [];
this.response.group.continent.split(",").forEach((l) => {
if ( uniques.indexOf(l) == -1 && l !== "") {
uniques.push(l);
}
});
console.log(" uniques : " uniques);
this.continent = uniques.join(", ");
},
}
mounted() {
this.removeDuplicates();
}
CodePudding user response:
TypeError: Cannot read properties of undefined (reading 'split')
This means that this.response.group.continent
is undefined
Analyzing your data, you should access the same with this.response[0].group.continent
CodePudding user response:
The error message suggests that this.response.group
is not a string, and by looking at your data, this.response
is an array of objects. Therefore you will need to iterate through in order to access the group
property of each object in the array. Using Array.forEach
should do the job with little modification to your logic:
const uniques = [];
this.response.forEach(({ group }) => {
group.continent.split(",").forEach((l) => {
if ( uniques.indexOf(l) == -1 && l !== "") {
uniques.push(l);
}
});
});
See a working example below (it's not a VueJS app, but contains the same logic as proof-of-concept):
const response = [{
"group": {
"continent": "ASIA,EUROPE,ASIA,EUROPE,ASIA,ASIA,EUROPE,EUROPE,ASIA,AUSTRALASIA,AUSTRALASIA,EUROPE,",
"location": "AS,AS,AS,AS,EU,AF,EU,AF,AU,AU,AU,AU,",
},
},
{
"group": {
"continent": "ASIA,EUROPE,AFRICA,EUROPE,ASIA,AFRICA,EUROPE,",
"location": "AS,AS,AS,AU,AU,",
},
},
{
"group": {
"continent": "ASIA,",
},
},
{
"group": {
"continent": "EUROPE,",
},
},
{
"group": {
"continent": "ASIA,EUROPE,",
"location": "AU,AU,"
},
},
];
const uniques = [];
response.forEach(({
group
}) => {
group.continent.split(",").forEach((l) => {
if (uniques.indexOf(l) == -1 && l !== "") {
uniques.push(l);
}
});
});
console.log("Uniques: " uniques);
const continent = uniques.join(", ");
console.log(continent);
Even better: use Set()
Array.prototype.flatMap()
A better way is simply to take advantage of ES6 features like Set()
, which stores a list of unique entries. Then it is just a matter of using Array.prototype.flatMap
Array.prototype.filter
(to remove empty entries) and passing the flattened array of continents into the set:
const continents = response.flatMap(({ group }) => group.continent.split(',')).filter(v => !!v);
const uniques = Array.from(new Set(continents));
See example below:
const response = [{
"group": {
"continent": "ASIA,EUROPE,ASIA,EUROPE,ASIA,ASIA,EUROPE,EUROPE,ASIA,AUSTRALASIA,AUSTRALASIA,EUROPE,",
"location": "AS,AS,AS,AS,EU,AF,EU,AF,AU,AU,AU,AU,",
},
},
{
"group": {
"continent": "ASIA,EUROPE,AFRICA,EUROPE,ASIA,AFRICA,EUROPE,",
"location": "AS,AS,AS,AU,AU,",
},
},
{
"group": {
"continent": "ASIA,",
},
},
{
"group": {
"continent": "EUROPE,",
},
},
{
"group": {
"continent": "ASIA,EUROPE,",
"location": "AU,AU,"
},
},
];
const continents = response.flatMap(({ group }) => group.continent.split(',')).filter(v => !!v);
const uniques = Array.from(new Set(continents));
console.log("Uniques: " uniques);
const continent = uniques.join(", ");
console.log(continent);