3

I have a Map which takes a Lecture as Key and an Array of Todos as value.

lecturesWithTodos: Map<Lecture, Todos[]> = new Map<Lecture, Todos[]>();

Now I first set the key of this Map without any value (because I get the Todos later).

student.semester.lectures.forEach((lecture) => {
    this.lecturesWithTodos.set(lecture, []);
});

Now I just would like to set my Todos to its specific Key.

todos.forEach((todo) => {
   this.lecturesWithTodos.get(lecture).push(todo);
});

But at this point it is always saying "Cannot read property 'push' of undefined". I know I can get it done, when I am using a string as Key, but I would like to use my Object instead, because it makes things easier for me later.

Is there a way how to get the get-Method working on this lecture object?

9
  • How does it "make things easier later on"? You would face the exact problem again while trying to retrieve data from the map Commented Aug 7, 2021 at 9:38
  • make sure you're using the same lecture reference that was added in the first forEach Commented Aug 7, 2021 at 9:38
  • Because when i iterate over that map I can get the values of my lecture object directly without the need of an extra lectures array. I checked a thousand times they are identically but the get-Method seems to not recognize it Commented Aug 7, 2021 at 9:41
  • Yes that is cause although the properties are same they are different objects, so .get(..) will not consider them to be equal. Commented Aug 7, 2021 at 9:43
  • is there another way how i can set the value of this object key? Commented Aug 7, 2021 at 9:49

1 Answer 1

1

Although it would be difficult to retrieve elements from the map later on, one way to achieve your objective is illustrated below.


Assuming that your types are as follows (change them as per your requirement)

interface Todos {
  id: number;
  name: string;
}

interface Lecture {
  id: number;
  name: string;
}

The given data:

 lectures: Lecture[] = [
    { id: 100, name: 'ENG' },
    { id: 200, name: 'PHY' },
    { id: 300, name: 'BIO' }
  ];

  todos: Todos[] = [
    { id: 100, name: 'Add' },
    { id: 100, name: 'Sub' },
    { id: 300, name: 'Mul' }
  ];

Logic to create the map

ngOnInit() {
   this.lectures.forEach(lecture => {
      this.lecturesWithTodos.set(lecture, []);
   });

   this.todos.forEach(todo => {
      const findLecture = this.findById(todo.id);
      const findAllTodos = this.findTodos(todo.id);

      if (findLecture && findAllTodos) {
        // implies that there is a previous todo added earlier
        this.lecturesWithTodos.set(findLecture, [...findAllTodos, todo]);
      } else if (findLecture) {
        // implies that its a new todo being set
        this.lecturesWithTodos.set(findLecture, [todo]);
      }
  });

}

/** Used to find Lecture based on todo id **/
findById(id: number) {
    return Array.from(this.lecturesWithTodos.keys()).find(e => e.id === id);
}

/** Used to find all previous todos based on todo id **/
findTodos(id: number) {
    // todos is a 2D array
    let todos = Array.from(this.lecturesWithTodos.values());

    // convert to 1D array for finding values from it
    return [].concat.apply([], todos).filter(e => e.id === id);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.