Priyamal
Priyamal

Reputation: 2969

async operator on undefined observable

I have a component which shows information only if the observable has data. but when I try to use async operator on the observable I don't see any value. I am confused with the way how async pipe works I think it takes some time to initialize the observable in that case async pipe will not do anything on undefined observable and that's why the component is not showing.

@Component({
  template: `
    <div *ngIf="todo$ | async as todo">
      <div {{todo.name}} </div>
    </div>   
  `
})
export class TodosComponent implements OnInit, OnDestroy {

  todo$: Observable<Todo>;

  constructor(private store: Store<State>) {}

  ngOnInit() {
    this.todo$ = this.store
      .pipe(select(selectTodos));
  }

  ngOnDestroy(): void {
  }
}

I know that async pipe will handle Observable but what if Observable is still undefined will async pipe handle that scenario too. if so is there any suggestion on what I might be doing wrong please note that I have subscribed and check if observable has data.

Upvotes: 1

Views: 5084

Answers (3)

Jonathan Stellwag
Jonathan Stellwag

Reputation: 4267

The async pipe also works with multiple, delayed and initially undefined observables. I made a stackblitz for you to see:

multiple-observable-assigns

It seems like you never get any data out of your select(selectTodos)

Upvotes: 3

Mike Hill
Mike Hill

Reputation: 3772

There are a couple of code issues. @Wandrille mentioned the first one -- you're referencing todos instead of todo in your template. In addition, you don't have a closing angle bracket for the opening <div> tag for the {{todo.name}} text. I would expect either of these issues to lead to a compilation error, though. Is your code exactly as listed?

Another likely issue would be that you're attempting to get the name element out of an array (i.e., perhaps todos$ should be of type Observable<Todo[]>). In this case, you will need to adjust your type declarations (and the selectTodos selector if applicable) and then iterate appropriately:

@Component({
  template: `
    <div *ngIf="todos$ | async as todos">
      <div *ngFor="let todo of todos">
        {{todo.name}}
      </div>
    </div>   
  `
})
export class TodosComponent implements OnInit, OnDestroy {

  todos$: Observable<Todo[]>;

  constructor(private store: Store<State>) {}

  ngOnInit() {
    this.todos$ = this.store
      .pipe(select(selectTodos));
  }

  ngOnDestroy(): void {
  }
}

Upvotes: 1

Jitendra
Jitendra

Reputation: 316

You should try this

<ul *ngIf="(todos$ | async).length">
  <li *ngFor="let todo of todos$ | async">{{todo.name}}</li>
</ul>

First you have to using *ngIf then you need to use for loop to print it

Upvotes: 1

Related Questions