Basic JavaScript - Record Collection

Tell us what’s happening:
Hello everyone!

I’ve been working on the Record Collection Challenge . When I run the tests, almost none of the assignments are validated although everything seems to work fine according to what I can see in my console.

I have copied my entire code below. If you have any idea why it is not accepted by the validation system, I’d be very grateful for your hints :slight_smile:

Your code so far

// Setup
const 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'
  }
};

// Only change code below this line

function updateRecords(records, 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 != "tracks" && value != "") {
    recordCollection[id][prop] = value;
  } 

//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" &&
    recordCollection[id].hasOwnProperty("tracks") == false
  ) {
    recordCollection[id][prop] = [];
    recordCollection[id][prop].push(value);
  }

 // 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 != "") {
    recordCollection[id][prop].push(value);
  } 

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

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

//Your function must always return the entire record collection object.
  return records;
}
updateRecords(recordCollection, 5439, 'artist', 'ABBA');

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36

Challenge: Basic JavaScript - Record Collection

Link to the challenge:

I’ve edited your code for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

This isn’t the variable you’re supposed to use

I pasted your code into fcc and it gave me the following syntax error in the console:

SyntaxError: unknown: 'return' outside of function. (55:2)

  53 |
  54 | //Your function must always return the entire record collection object.
> 55 |   return records;
     |   ^
  56 | }
  57 | updateRecords(recordCollection, 5439, 'artist', 'ABBA');

There’s an extra } after the line delete recordCollection[id][prop]
but even after removing that, many of the tests (almost all) failed.

I will look into this a bit more but just wanted to let you know about this first issue.

As said, you are supposed to use the records parameter and not the recordCollection object directly.

Thank you very much, I didn’t know!

1 Like

Ah yes… of course! thank you!!

This was the issue I was having as well, but I don’t understand how it works this way.

My understanding is that to reference a property contained within an object you use the object’s name as the first part of the path. So in this case, how does the function know that it should reference the recordCollection object when the name of the object isn’t used? How do I know if I should use something like records instead?

1 Like

records is the name of the object inside of the function.

You look at the call site and the function definition.

The external object is passed to the function call as an argument (call site).

updateRecords(recordCollection, 5439, "artist", "ABBA")

The first parameter in the updateRecords definition is records (function definition)

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

So inside the function records is the same as recordCollection


Whenever you see a function accepting parameters you should always use the parameters. Even if the value exists outside the function if they are passed to the function that is the value you should use. That is the point of passing the value.

A “true” function accepts and returns values, they do not just run and cause side effects. Such a “function” (not a function) is sometimes called a procedure but you won’t hear that in JS land very often and all JS functions return a value (i.e. undefined if nothing else).

Let’s write a function that returns the name property on literally any object.

function getName(literallyAnyObjectWithANameProperty) {
  return literallyAnyObjectWithANameProperty.name;
}

We can use a whole slew of objects when calling this bad boy

const me = {
  name: "Colin"
};

const myDog = {
  name: "Chiro"
};

const myFriend = {
  name: "Jace"
};

getName(me); // evaluates to "Colin"
getName(myDog); // evaluates to "Chiro"
getName(myFriend); // evaluates to "Jace"

We can even use an object literal inside the function call

getName({
  name: "Quarl88"
}); // evaluates to "Quarl88"

Notice that the name of the parameter inside the getName function has nothing in common with the names of the object variables.

1 Like

@JeremyLT I noticed your recently closed topic/update/revamp for the Record Collection question. TBH I’ve struggled with the wording and the logical flow of the requirements listed. I resisted checking the solutions for quite a while, but eventually looked. I’ve since adopted a similar single conditional term for each if (…) block, which has drastically simplified my solution to this:

function updateRecords(records, id, prop, value) {
  if (value == "") {
    delete records[id][prop];
  }
  else {
    if (prop == "tracks") {
      if (records[id].hasProperty("tracks")) {
        //*** Do nothing, aka "no operation" aka  "nop"
      }
      else {
        records[id][prop] = [];
      }
      records[id][prop].push(value);
    }
    else {
      records[id][prop] = value;
    }
  }
  return records;
}

My main question for this is: with the introduction of arr.hasOwnProperty("abc") earlier in the lesson, why is there not a solution that actually uses this?

I also think the list of requirements could be more newbie friendly, but I also think it is a good indication that real-life requirements can often be initially presented in a way that won’t mimic the logic of the solution. Perhaps a second exercise could retain the original (or current) order of requirements, with a simpler first exercise that forces usage of recently introduced concepts.

But there is?

An update to this challenge just rolled out a couple of days ago.

EDIT: Also hasProperty should be hasOwnProperty

When possible, I would highly suggest avoiding the if blocks where nothing is happening. You can simplify this even further by just checking to see if the property doesn’t exist within the object and avoid a useless if-else statement:

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

Thanks!

I see the difference now in the requirements. I’ve been on this for several weeks now (due to limited time) and somehow missed the update. Using console.log helped a lot.

Due to the scrolling in the solution, I also missed that hasOwnProperty was offered.

Yes I corrected that in my subequent code, but never corrected my clipboard.

Thank you!
I got so stuck on this, specifically because in the output it only states what output it was expecting. So I set up a thousand console log lines to make sure that these outputs matched mine, and it did for every prompt!

I could not figure out what it was because I got so used to that Collection name… But it makes sense! Moving on, thanks again!