PrototypeXenon PrototypeXenon - 6 months ago 97
Javascript Question

Editing an array inside an object inside an object

I'm working on a challenge for a coding class, and for some reason my code won't work. I was given the following:

// Setup
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"
}
};
// Keep a copy of the collection for tests
var collectionCopy = JSON.parse(JSON.stringify(collection));

// Only change code below this line


I was supposed to fulfill the following:


  • After updateRecords(5439, "artist", "ABBA"), artist should be "ABBA"

  • After updateRecords(5439, "tracks", "Take a Chance on Me"), tracks should have "Take a Chance on Me" as the last element.

  • After updateRecords(2548, "artist", ""), artist should not be set

  • After updateRecords(1245, "tracks", "Addicted to Love"), tracks should have "Addicted to Love" as the last element.

  • After updateRecords(2548, "tracks", ""), tracks should not be set



My code is only fulfilling the first and 4th requirements. When running
updateRecords(5439, "tracks", "Take a Chance on Me");
or
updateRecords(2548, "tracks", "");
, I get
TypeError: Cannot read property 'push' of undefined
. When I run
updateRecords(2548, "artist", "");
, I get
TypeError: Cannor convert undefined or null to object
.

My code looks like this:

// Only change code below this line
function updateRecords(id, prop, value) {
if (value !== "" && prop !== "tracks"){
collection[id][prop] = value;
}
else if (value !== "" && prop == "tracks"){
var currentAlbumTracks = collection[id].tracks;
currentAlbumTracks.push(value);
}
else if (value === ""){
delete collection.id.prop;
}
return collection;
}


Any idea what's going on?

EDIT: I've changed my code a bit. Now I have:

function updateRecords(id, prop, value) {
var currentAlbumTracks = collection[id].tracks;
if (value !== "") {
if (prop !== "tracks"){
collection[id][prop] = value;
}
else if (prop == "tracks"){
if (currentAlbumTracks) {
currentAlbumTracks.push(value);
}
else if (currentAlbumTracks === ""){
collection[id].tracks = [value];
}
}
}

return collection;
}

Answer

We have two mistakes here.

  1. collection[id].tracks is undefined in some cases, so before pushing values you need to define it, So

    var currentAlbumTracks = collection[id].tracks;
    currentAlbumTracks.push(value);
    

    became

    collection[id].tracks = collection[id].tracks || []; //Take existing or create new
    collection[id].tracks.push(value);
    
  2. Your dot notation is incorrect, more info here

    So

    delete collection.id.prop;
    

    becomes

    delete collection[id][prop];
    

Overall including all rectification, We can make following function

function updateRecords(id, prop, value) {
  if (value !== "" && prop !== "tracks"){
    collection[id][prop] = value;
  }
  else if (value !== "" && prop == "tracks"){
    collection[id].tracks = collection[id].tracks || [];
    collection[id].tracks.push(value);
  }
  else if (value === ""){
    delete collection[id][prop];
  }
  return collection;
}