Accessing Objects With Bracket Notation

Alice Moretti   March 11th, 2022

During these weeks, I have decided to revise some JavaScript while pushing the pram at home and making my lovely daughter fall asleep. It turned out a great way to do this is by following the JavaScript Algorithms and Data Structure course on FreeCodeCamp. The lectures are concise and straight to the point (excellent for those who might be a bit sleep deprived like me:-) ). The FCC community is active and helpful, and I can access the learning platform through my phone with a single hand (while the other one is busy pushing the stroller...).

The exercise

While tackling the JavaScript object module, I got stuck over an exercise involving accessing objects with bracket notation. So far I had always been accessing objects through dot notation and in my mind using another approach was just a fancier way to obtain the exact same result. Turns out I was wrong...

The exercise gives the following object (as you can see, the properties may vary across the different nested objects): 

var recordCollection = {
  2548: {
    albumTitle: 'Slippery When Wet',
    artist: 'Bon Jovi',
    tracks: ['Let It Rock', 'You Give Love a Bad Name']
  },
  2468: {
    albumTitle: '1999',
    artist: 'Prince',
    tracks: ['1999', 'Little Red Corvette']
  },
  1245: {
    artist: 'Robert Palmer',
    tracks: []
  },
  5439: {
    albumTitle: 'ABBA Gold'
  }
};

And asks you to write a function to update its properties. The function parameters should be the object to be updated, records, containing a musical album collection, an id, a prop (like artist or tracks), and a value. Below is the starting function provided in the assignment instructions:

function updateRecords(records, id, prop, value) {
  return records;
}

The instructions in detail are the following:

  • If prop isn't tracks and value isn't an empty string, update or set that album's prop to value.

  • If prop is tracks but the album doesn't have a tracks property, create an empty array and add value to it.

  • If prop is tracks and value isn't an empty string, add value to the end of the album's existing tracks array.

  • If value is an empty string, delete the given prop property from the album.

  • The function must always return the entire record collection object.

The first thoughts that came to my mind while trying to approach the problem were:

  1. To check the requirements I should probably use an if...else if statement;

  2. Each entry is identified by an id that indicates to the algorithm which nested object needs to be updated;

  3. id and prop parameters need to be variables as their value will keep on changing while iterating over "records".

Point three was the one I didn't know how to tackle as, so far, I had been accessing objects with dot notation which doesn't allow the use of variables.

Before diving into the solution, let's first take a step back to understand the main difference between bracket and dot notation.

Accessing objects with dot notation

When we access an object with dot notation, we write the object name followed by a dot and the property name we want to access. To access the vegetable property on the following object, we would write:

myFood.vegetable

and the result would be "carrot" .

let myFood = {
fruit: "apple",
vegetable:"carrot",
dessert: "chocolate cake"
}

So far so good...This approach though has a limitation and that is we are hard-coding the property name. What if I wanted to write a function that updates each of the properties? That would require the use of a variable and the dot notation doesn’t allow it.

Considering the myFood object, if we write the function below and we run it by passing in the argument fruit, we get undefined.

function printMyFood (food){
console.log(myFood.food);
}

printMyFood (fruit)

That is because, when we use dot notation, JavaScript searches for the property with the exact same name after the dot (food in this case) and, on our object, there is no food key.

Accessing objects with bracket notation

When we access an object with bracket notation, we write the object name followed by square brackets. Inside the square brackets, the property name is specified as a string (or number). With this in mind, the above code can be rewritten as follows:

myObj ["vegetable"]

Likewise, the function printMyFood can be rewritten as follows and the console this time would print “apple”.

function printMyFood (food){
console.log(myFood[food]);
}

printMyFood (“fruit”)

Bracket notation allows a variable to specify the property name and that variable can define which property I want to use at runtime. That is possible as Javascript automatically transforms what is inside the square brackets into a string and then retrieves the corresponding property

In addition, when the property we want to access contains a space in its name, then we have to use the bracket notation as the dot one doesn’t allow it. 

const myLuch = {
“main course” : “pasta”,
“side dish”: “salad”
}

To access the main course key we would write

myLuch[“main course”]

The solution

With this in mind, I started to think of a solution that implemented the bracket notation while tackling the exercise instructions one by one:

1. If prop isn't tracks and value isn't an empty string, update or set that album's prop to value.

function updateRecords (records, id, prop, value) {
if (prop!== "tracks" && value !== " "){
records[id][prop] = value
}
}

The above code checks that the property is not tracks and its value is not an empty string. If that is the case, then we access the property nested inside the object with the given id and we modify its value. With the syntax records[id][prop] = value we either update the property value or we create the key from scratch and add a value to it.

2. If prop is tracks but the album doesn't have a tracks property, create an empty array and add value to it.

else if (prop === "tracks" && records[id].hasOwnProperty("tracks") === false) {
    records[id][prop] = [value];
 }

In the above code, we use the hasOwnProperty() method that checks if the object contains the given property and returns a boolean. If the property tracks doesn’t exist, we create an array and then we add the values inside it.

3. If prop is tracks and value isn't an empty string, add value to the end of the album's existing tracks array.

} else if (prop === "tracks" && value !== "") {
    records[id][prop].push(value);
  }

The above case is when the tracks array already exists and therefore we can use the array method push() to add a new value at the end of it.

4. If value is an empty string, delete the given prop property from the album.

 else if (value === "") {
    delete records[id][prop];
  }

Here, to delete the property we use the delete operator.

With this in mind the complete code is the following:

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

This was a simple exercise that nonetheless made me understand how useful it can be to use the bracket notation over the dot notation while accessing a JavaScript object.