0

I have the following object:

var watchObject = {};

Here is the following code I'm trying to accomplish; if it exists in the object I want to append it and if it doesn't exist I want to create a new key/value pair. The key value pair looks like "23": [blah]. So if the "23"(data.room) exists in the object I will push another to it like "23":[blah,bleh].

//assume data.room is defined elsewhere and data.videoId is defined elsewhere

if (data.room in watchObject) {
    watchObject[data.room].push(data.videoId);
} else {
    watchObject[data.room] = data.videoId;
}

I tried the above, I thought it would work, but it keeps saying:

"TypeError: watchObject[data.room].push is not a function"

I've also tried assigning data.room into a variable without any luck:

if (data.room in watchObject) {
   let tempRoom = data.room;
   watchObject.tempRoom.push(data.videoId);
   //watchObject[data.room].push(data.videoId);
} else {
    watchObject[data.room] = data.videoId;
}

And I get this error:

"TypeError: Cannot read property 'push' of undefined"

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • `watchObject.tempRoom.push(data.videoId);` looks for a property named `tempRoom` on `watchObject`. It is completely different from `watchObject[data.room].push(data.videoId);`. which looks for a property named the same as the value of `data.room`. `watchObject[tempRoom].push(data.videoId);` would have had the same effect as the original. See [Accessing an object property with a dynamically-computed name](https://stackoverflow.com/q/4244896/215552) – Heretic Monkey Jun 26 '23 at 16:27

3 Answers3

0

It's because watchObject[data.room] is blah (i.e. videoId) rather than [blah] (i.e. array of videoIds] hence the error push is not a function because a string won't have a push method.

You need this:

if(watchObject[data.room] == null) {
  watchObject[data.room] = []
}
// now you can safely push to the array
watchObject[data.room].push(data.videoId)
Suyash Gulati
  • 511
  • 7
  • 21
Dusan Jovanov
  • 547
  • 5
  • 21
  • 1
    I'm not entirely sure why this is downvoted, I tried this approach and it worked out for me. Thank you I appreciate it! – Ethan Gordon Jun 23 '23 at 00:15
  • i think it was downvoted by someone because there is a correction required in your answer. Made some edits thanks. – Suyash Gulati Jun 24 '23 at 20:28
0

The issue is that once you create the entry via this code...

watchObject[data.room] = data.videoId;

it is not an array so the next time you try this code...

watchObject[data.room].push(data.videoId);

it will fail with the error you see.

A simple option here is to lazily create an array before pushing

const watchObject = {};
const arr = [{ room: "23", videoId: "blah" }, { room: "23", videoId: "bleh" }];

arr.forEach((data) => {
  // create an empty array if it does not exist
  watchObject[data.room] ??= [];

  // now push
  watchObject[data.room].push(data.videoId);
});

console.log(watchObject);

See Nullish coalescing assignment (??=)

Phil
  • 157,677
  • 23
  • 242
  • 245
  • Thank you for the info on the ??= operator I didn't know that was a thing. I will mark Dusan's as the answer simply because it is more intuitive at first glance without knowing the operator. But this is good to know. Thanks again! – Ethan Gordon Jun 23 '23 at 00:17
-1

You're almost done. But you have a mistake. Try this:

let watchObject = {};

// Init `data`
if (watchObject[data.room]) {
  watchObject[data.room].push(data.videoId);
} else {
  watchObject[data.room] = [data.videoId]; // this is the line you need to change
}

This will work well.

Michael M.
  • 10,486
  • 9
  • 18
  • 34