What is 'Record Collection' Trying to Teach Me?

Tell us what’s happening:
Forgive me if I am making an unusual request or seem difficult. I know this challenge is likely simpler than it seems to me, but I have spent two hours trying to solve and am losing sleep for it.

My code below is as far as I got on my own. I brought in the conditions as pseudocode to help, which they did a little. And those two hours include reviewing the solution, watching the video, and searching the forum, trying to get something to come together.

But it still makes no sense to me. A primary difficulty, I believe, is the language; I don’t clearly understand what I am being asked to do here.
By now, that’s not important. I don’t want the solution explained to me. I don’t want to know why the solution works.

I want to understand what I am supposed to have learned from this challenge. If I know that, then maybe this will make sense to me. But, until then, I cannot be satisfied simply moving on having learned nothing. Would you please help me?

Your code so far


// Setup
var collection = {
  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'
  }
};

// Only change code below this line
function updateRecords(object, id, prop, value) {

// 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 === 'tracks') {
  object[id][prop] = [];
}

// 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.

if(value === '') {
  delete object[id][prop];
}

  return object;
}

updateRecords(collection, 5439, 'artist', 'ABBA');

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36.

Challenge: Record Collection

Link to the challenge:

Hi and welcome to the forum.

The purpose of this challenge is to integrate multiple previous skills into a more complex task. Coding is about combining single skills in more complex ways to let the computer do new things.

1 Like

This challenge introduces JSON…
Whenever you’ll work with API’s in any language or if you’re doing web scraping, or else, need to get some data from web to your mobile app, JSON is returned from the server, and you’ve to extract data from that…
Read more about JSON


you need to understand javascript notations to access data inside object attributes


You’ll also have practice of conditional statements.

Sorry, if my words are confusing. I’m not good in explaining things!!

Knowledge of the JSON format really does not help solve this challenge. It’s more about combining knowledge about accessing object properties, array handling, conditionals, which you mentioned.

I had an idea: if I don’t understand the given prompt, then why not re-write it? So I did. First, I defined terms so they’d be clear. Second, I wrote a slightly adjusted list of conditions and ordered them logically. Finally, using the target results below the buttons, I provided examples for which conditions would satisfy those results.

Definitions:
collection is an object;
2548 is an id, it is a nested object and can be accessed via object[id];
albumTitle, artist, tracks are props, and can be accessed as object[id][prop];
‘Slippery When Wet’, ‘Bon Jovi’, etc. are all values, and can be accessed as the value of a prop i.e. object[id][prop];

Example: ‘You Give Love a Bad Name’ is stored as collection[2548]['tracks'][1]

Conditions:

  1. Function must always return the entire object (e.g. collection);

  2. If value === ""
    then delete object[id][prop];

  3. Else if prop === 'tracks' but there is no
    object[id]['tracks'] OR 4. the value of 'tracks' is not empty
    then object[id][prop] = object[id][prop] || [];
    object[id][prop].push(value);
    e.g. collection[5439][tracks] = []; collection[5439]['tracks'].push('Take A Chance on Me');
    e.g. collection[2468]['tracks'] = collection[2468]['tracks']; collection[2468]['tracks'].push('Free');
    e.g. collection[1245]['tracks'].push('Addicted to Love');

(5). Else prop != 'tracks' && value != " "
then set that album’s property i.e object[id][property] = value;
e.g. collection[5439][artist] = 'ABBA';
e.g. collection[1245][albumTitle] = 'Riptide';

Hopefully, this helps clear up any confusion for other coders and does not generate more. :+1:

My takehome from the challenge is you have to focus on dot notation and bracket notation. It’s only given maybe a line in the “lecture” part, but it will absolutely sink you if you can’t do it. At least that’s how it was for me.

I thought dot notation wouldn’t really work for this challenge, since you’re using variable names to access the object properties as opposed to the property names themselves.

I’m not 100% on the differences between dot notation and bracket notion. I gather that dot notation is preferred, but this passage from Eloquent JavaScript…

When using a dot, the word after the dot is the literal name of the property. When using square brackets, the expression between the brackets is evaluated to get the property name. Whereas value.x fetches the property of value named “x”, value[x] tries to evaluate the expression x and uses the result, converted to a string, as the property name.

…that’s unintelligible to me. Let me see if I can do better.

  key4: ['valGroup', {
    1: 'think',
    2: 'blue', 
    drei: 'count',
    two: '2'
  }]
}


console.log(obj['key4'][1][1]);         // 'think'
console.log(obj.key4[1]['2']);          // 'blue'
console.log(obj.key4[1]['drei']);       // 'count'
console.log(obj.key4[1].two)            // '2'
console.log(obj.key4[1].2);             // SyntaxError

Why the error? It’s a property, isn’t it? Well, yes but property names are strings even when they are numbers. Check it out:

typeof(obj.key4[1][1]);      //string

So why doesn’t (obj.key4[1].2) work and yet (obj.key4[1][2]) does? It’s because the latter evaluates the property in brackets as a string and returns its value, while the former just grabs the property, sees that it isn’t a string, and then complains to you about syntax.
“I wanted you to read it as a string, computer.”
“You didn’t tell me that you wanted me to read it as a string, human.”
“I apologize, computer. I will be more proactive communicating my needs in the future.”

2 Likes

It’s good that you’ve isolated that passage and pointed it out as important. I’ve found that reading such a thing, over and over, slowly, is very helpful. Especially since I tend to read very fast in my lib arts way, and almost semi-skim even things that are very important.

The different ways of accessing object properties is frankly rather forbidding for a beginner, which imo is why this FCC challenge is disproportionately hard.

Dot notation is not particularly preferred or better.

Think about it this way:

An object has properties. These properties are accessed by some name.

If you know the name, you can access the property directly with dot notation:

const myObj = {
    name: "Bananas",
    food: "candy",
};

let myFood = myObj.food;
console.log(myFood);

However, when you use the property name directly using dot notation, you are hardcoding that property. If you don’t know when you are writing your code what property you will need, such as when you are writing reusable code, then you will want to use bracket notation:

const myObj = {
    name: "Bananas",
    food: "candy",
};

let myFood = myObj["food"];
console.log(myFood);

Now for some bracket notation with code reuse

// log property contents
function talkToMe(anObj, aProp) {
    console.log("My " + aProp + " is " + anObj[aProp]);
}

// test object
const myObj = {
    name: "Bananas",
    food: "candy",
};

// let's make it talk!
talkToMe(myObj, "name");
talkToMe(myObj, "food");

See it live on repl.it

Numbers as variable names are always a bad idea, so you’ll want to steer away from them.

1 Like

it’s because a number is not a valid identifier - you can use dot notation for everything that is also a valid variable name, a number is not

try with
var 2 = "something"
you get the same error

2 Likes

Also compare:

myObj["food"]

vs

myObj[food]

The first one correctly accesses the property, just like myObj.food would. The second one gives an error.

VM389:1 Uncaught ReferenceError: food is not defined

Why?

Inside the brackets, if it’s not enclosed in quotes, its viewed as a variable, and food is not a variable we’ve defined.

But what if we define it?

const food = "food"

Now there is a variable, food, that evaluates to “food” (a string). That string matches the key of myObj we are trying to access. And voila:

myObj[food]; //"banana"

That would be pretty confusing , though, using the same word as the name of the variable as the string it points to that is meant to access the key of the object.

3 Likes

Ah, now my knowledge has expanded has expanded further. Now I know when to use one or the other.