Breaking down a function – updateRecords()

A friend asked me to explain this code in detail for a function called updateRecords() that they were studying on an online learning site. Actually they expect you to create the guts of the function yourself and make sure it meets certain requirements. This is my solution and explanation. It is designed for somewhat beginners so Its deliberately not succinct because the purpose is to explain whats going on in detail in a simple way that is easy to follow. At the end I will demonstrate alternative ways to write the same function in a more concise manner.

Firstly here is the code without any comments.

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));

function updateRecords(id, prop, value) {
  var album = collection[id]; 
  if(prop === "tracks") { 
    if(value !== "") { 
      album[prop].push(value); 
	} else if(value === "") {
		delete album[prop];	
	}
  } else if(value !== "") { 
    album[prop] = value; 
  } else if(value === "") {
    delete album[prop]; 
  }	
  return collection; 
}
// Alter values below to test your code
updateRecords(5439, "artist", "ABBA");

The best way to explain any code in my opinion is to start with the most simple and gradually work up to the more complex, always remembering that greater complexity doesn’t necessarily mean harder or more advanced code, it just means more things are going on at the same time. If we break those things down one at a time we can see the code is not as hard as we might have initially thought.

We have a javascript object called “collection” which itself contains 4 other objects. Each object represents an album in a music collection.

Our updateRecords() function allows us to:

  1. Update a simple string property like “album” or “artist” with a new value.
  2. Add a simple property and set a value if the property doesn’t already exist.
  3. Delete a simple string property like “album” or “artist”.
  4. Add an item to an array if that array already exists.
  5. Delete the entire array.

Lets simplify things and assume that we only want our function to be able add or update a simple string property. For the time being we wont be able to delete a property or modify the array.

This is all the code we would need for our function:

function updateRecords(id, prop, value) {
  // which child object in our main 
  //collection object e.g. collection[5439]
  var album = collection[id]; 
  
  // update an existing property or add a new property
  // e.g. album["artist"] = "Artist Name"
  album[prop] = value;

  // return the updated collection
  return collection; 
}

// then call the function with some arguments
// adds an artist property to record 5439
// and sets the value to ABBA
updateRecords(5439, "artist", "ABBA");

Much simpler. We can even omit the album variable and just update or add our property like this:

collection[id][prop] = value;

// which is the equivalent of these two lines
var album = collection[id]; 
album[prop] = value;

But lets not get carried away just yet with short-handing our code. As you can see there is not much to it. So why is the original code much longer and more complicated looking? Because we want to add the ability to delete as well as deal with an array. This requires us to build checks or tests into our code which makes it get more complex. But we can tackle that a bit at a time. For now I will keep the comments spare until the end. So here is our simple function so far without comments:

function updateRecords(id, prop, value) {
  var album = collection[id]; 
  album[prop] = value;
  return collection; 
}

Now lets add the ability to delete a simple property:

function updateRecords(id, prop, value) {
  var album = collection[id]; 

  if(value !== "") { // if value is not an empty string
    album[prop] = value; // add or update the value
  } else if(value === "") { // but if the value is an empty string
    delete album[prop]; // then delete that property entirely
  }

  return collection; 
}

Now before updating or adding our property we check to see if the value we supply as our argument is an empty string or not. If it is an empty string we delete the associated property completely. If the third argument is a string containing a value, we just update that property or add it if it didn’t already exist.

// function call with a non-empty value
// adds property "artist" with value "ABBA" or updates "artist" to "ABBA"
updateRecords(5439, "artist", "ABBA");

// function call with an empty value
// deletes "arist" property from record 5439
updateRecords(5439, "artist", "");

So running some checks required us to add an if else statement. Okay, but what if we want to be able to add a new song title to our tracks array? Easy just run some more checks with an if statement and a nested if else statement:

// if statement to check if second argument supplied is "tracks"
if(prop === "tracks") { // if yes we then run a nested if else statement
  
  if(value !== "") { // if value is not an empty string
    
	// add value to "tracks" array
	album[prop].push(value); 
  
  } else if(value === "") { // if value is empty string
    
	delete album[prop];// delete  the "tracks" array	
   
  } // close the nested if else

} // close the if

If the argument supplied to the prop parameter is “tracks”, then we run the nested if else. Otherwise we skip all of that and move onto the next part of the code that deals with simple strings and not arrays. So our final code, with comments and spaces for readability, would look like this:

function updateRecords(id, prop, value) {
	
  // which child object in our main collection object 
  var album = collection[id]; 
  
  // if we want to update the "tracks" property
  if(prop === "tracks") { 
    
	// if value is not an empty string
	if(value !== "") { 
      
	  // add value to "tracks" array
	  album[prop].push(value); 
	
	// if value is an empty string
	} else if(value === "") {
	
	  //delete the "tracks" array
	  delete album[prop];	
	
	}
  
  // below code is only used if updating another property besides "tracks" array
  // in other words if second argument was anything but "tracks"
  } else if(value !== "") { // if value is not an empty string
    
	// add or update the value
	album[prop] = value; 
  
  // but if the value is an empty string
  } else if(value === "") { 
    
	// then delete that property 
	delete album[prop]; 
  
  }	
  
  // return the updated collection
  return collection; 

}

In my next update I will demonstrate how to make this code more succinct by using a bit of shorthand.