Reputation: 4170
I have a snippet of code that updates records in a json object representing a musical album collection. The function written here updates the records given an album ID, a property ("tracks"), and a value ("albumName")
The error I get below is:
"message": "Uncaught TypeError: collection[id][prop].push is not a function",
var collection = {
"2548": {
"album": "Slippery When Wet",
"artist": "Bon Jovi",
"tracks": [
"Let It Rock",
"You Give Love a Bad Name"
]
},
"2468": {
"album": "1999",
"artist": "Prince",
"tracks": [
"1999",
"Little Red Corvette"
]
},
"1245": {
"artist": "Robert Palmer",
"tracks": [ ]
},
"5439": {
"album": "ABBA Gold"
}
};
// Only change code below this line
function updateRecords(id, prop, value) {
if(!value){
delete collection[id][prop];
return collection;
}
if(prop === "tracks"){
if(!collection[id].hasOwnProperty('tracks')){
collection[id].tracks="";
}
if(value){
collection[id][prop].push(value);
}
} else {
collection[id][prop] = value;
}
return collection;
}
updateRecords(5439, "tracks", "Take a Chance on Me");
Some other test case scenarios
Upvotes: 0
Views: 379
Reputation: 65855
A simple log of id
and prop
in that section shows that id = 5439
and prop = tracks
and the object with an id
of 5439
doesn't have a tracks
property. So, collection[id][prop]
is returning undefined
and undefined
does not have a push
method.
The solution would be to test for the existence of the tracks
property and to create it if it doesn't exist.
var collection = {
"2548": {
"album": "Slippery When Wet",
"artist": "Bon Jovi",
"tracks": [
"Let It Rock",
"You Give Love a Bad Name"
]
},
"2468": {
"album": "1999",
"artist": "Prince",
"tracks": [
"1999",
"Little Red Corvette"
]
},
"1245": {
"artist": "Robert Palmer",
"tracks": [ ]
},
"5439": {
"album": "ABBA Gold"
}
};
// Only change code below this line
function updateRecords(id, prop, value) {
if(!value){
delete collection[id][prop];
return collection;
}
if(prop === "tracks"){
if(!collection[id].hasOwnProperty('tracks')){
collection[id].tracks="";
}
if(value){
// If the property doesn't exist...
if(!collection[id][prop]){
// Create it and initialize it to an empty array
collection[id][prop] = [];
}
// Now, it's safe to push the new value into the array
collection[id][prop].push(value);
console.log(collection[id]); // <-- Test
}
} else {
collection[id][prop] = value;
}
return collection;
}
updateRecords(5439, "tracks", "Take a Chance on Me");
Upvotes: 1
Reputation: 2664
You may want to initialize an empty array for an item id that is not found in the collection
like so:
var collection = {
"2548": {
"album": "Slippery When Wet",
"artist": "Bon Jovi",
"tracks": [
"Let It Rock",
"You Give Love a Bad Name"
]
},
"2468": {
"album": "1999",
"artist": "Prince",
"tracks": [
"1999",
"Little Red Corvette"
]
},
"1245": {
"artist": "Robert Palmer",
"tracks": [ ]
},
"5439": {
"album": "ABBA Gold"
}
};
// Only change code below this line
function updateRecords(id, prop, value) {
if(!value){
delete collection[id][prop];
return collection;
}
if(prop === "tracks"){
if(!collection[id].hasOwnProperty('tracks')){
collection[id].tracks=[]; // notice new array initialization
}
if(value){
collection[id][prop].push(value);
}
} else {
collection[id][prop] = value;
}
return collection;
}
updateRecords(5439, "tracks", "Take a Chance on Me");
Upvotes: 1
Reputation: 6058
+1 for providing a working sample to reproduce the issue.
The issue is with the line collection[id].tracks=""
it should be collection[id].tracks=[]
See the updated example below:
var collection = {
"2548": {
"album": "Slippery When Wet",
"artist": "Bon Jovi",
"tracks": [
"Let It Rock",
"You Give Love a Bad Name"
]
},
"2468": {
"album": "1999",
"artist": "Prince",
"tracks": [
"1999",
"Little Red Corvette"
]
},
"1245": {
"artist": "Robert Palmer",
"tracks": [ ]
},
"5439": {
"album": "ABBA Gold"
}
};
// Only change code below this line
function updateRecords(id, prop, value) {
if(!value){
delete collection[id][prop];
return collection;
}
if(prop === "tracks"){
if(!collection[id].hasOwnProperty('tracks')){
collection[id].tracks=[];
}
if(value){
collection[id][prop].push(value);
}
} else {
collection[id][prop] = value;
}
return collection;
}
updateRecords(5439, "tracks", "Take a Chance on Me");
console.log(collection[5439])
Upvotes: 3
Reputation: 266
.push is a function of Array object. However, you are using it on a String. You need to initialize it to an Array instead of String
if(!collection[id].hasOwnProperty('tracks')){
collection[id].tracks=[];
}
Upvotes: 1