2

This seems to be a very awkward problem:

I am accessing my modal.service.ts using the following code: this.modalService.add('test');

My modal.service.ts looks like the following:

import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class ModalService {
    private modals: any[] = [];

    add(modal: any) {
        // add modal to array of active modals
        this.modals.push(modal);
    }

    remove(id: string) {
        // remove modal from array of active modals
        this.modals = this.modals.filter(x => x.id !== id);
    }

    open(id: string) {
        // open modal specified by id
        const modal = this.modals.find(x => x.id === id);
        console.log(this.modals)
        console.log(this.modals[0])
        //modal.open();
    }

    close(id: string) {
        // close modal specified by id
        const modal = this.modals.find(x => x.id === id);
        modal.close();
    }
}

Why does console.log(this.modals[0]) give me undefined when this.modals gives me an output of the array with 'test' being at pos 0?

This is the console output: Console Output

4
  • 1
    when this.modals gives me an output of the array with 'test' being at pos 0? Where? Can you post a screenshot Commented Oct 25, 2019 at 9:08
  • Please find a screenshot attached. Commented Oct 25, 2019 at 9:39
  • Can you provide a stackblitz? Commented Oct 25, 2019 at 9:40
  • 1
    if u log array with item it would be look like ["test"], you have in consolo []. this is wierd Commented Oct 25, 2019 at 10:15

1 Answer 1

6

It is a problem with (or feature of) browser's console. It shows that 0th element of this.modals is "test" because at the moment of inspecting it is. But at the moment of executing it is empty.

{
  const anArray = [];
  console.log(anArray);
  console.log(anArray[0]);
  anArray.push("foo");
}
// Browser's output:
// >>> []  <-- But expanded it will show [0: "foo"].
// >>> undefined

{
  const anArray = [];
  anArray.push("foo");
  console.log(anArray);
  console.log(anArray[0]);
}
// Browser's output:
// >>> ["foo"]  <-- See. Already pre-filled on display.
// >>> foo

So what you actually have is a race condition. Your this.modals is filled after open is called.

Sign up to request clarification or add additional context in comments.

2 Comments

I see, thanks. Tough to debug if you don't know that Chrome is logging asynchronously. What would be the best approach to wait for it to not be undefined? Any chance using Promises?
I do not know what other part of code looks like and I am not an expert on Angular. So I can't help much. The right thing would be to make sure that add gets called before open. If you can't guarantee then it is going to be complicated. You can try to play with async and/or promises. Other option would be to have pendingModalOpenings. Which would be filled on open if modal does not exist yet. And then in open you would check if there is anything waiting in pendingModalOpenings and open just added modal if needed.

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.