0

This bug is related with this.events$ initialized in ngOnInit()

This question is very similar to others but still slightly different when it comes to execution time.

I have simple zip to merge two observable like:

zip(this.eventService.searchedEvent$, this.events$)
    .subscribe(([input, events]) => console.log(input, events))

The problem is that I don't want to execute this in ngOnInit() where it totally works fine. My point is to execute it in ngAfterViewInit() when data is loaded. Flow of app:

  1. Load data in component by ngOnInit().

  2. Emit value from search bar via service, like here: https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service

  3. Get values from service in ngAfterViewInit()

Notice that when I simply do subscribe() to observable this works:

  ngAfterViewInit() {
    // this.eventService.searchedEvent$.subscribe(console.log)
  }

Unfortunately I need to merge observable from search input and observable of datasource so I am trying to combine them both:

 ngAfterViewInit() {
     zip(this.eventService.searchedEvent$, this.events$)
    .subscribe(([input, events]) => console.log(input, events))
   }

But still it is not fired. Why it works in ngOnInit() but not in ngAfterViewInit() ever is simple subscription is emitted dynamically in ngAfterViewInit() ? Any solution for this?

EDIT:

ngOnInit() {

    this.isLoading$ = this.store.pipe(select(selectEventsLoading))

    this.events$ = this.paginationService.page$.pipe(
      switchMap(pageIndex => this.store.pipe(
        delay(0),
        select(selectEventsPageByGenre(this.musicGenre, { pageIndex: pageIndex, pageSize: PAGE_SIZE })),
        map(events => {

          if (events.length > 0) {
            return events;
          }

          this.store.dispatch(new EventsPageRequested({
            musicGenre: genreToEnum(this.musicGenre),
            page: {
              pageIndex: pageIndex,
              pageSize: PAGE_SIZE
            }
          }));

          return [];
        }),
        tap(events => {
          this.isEmpty$ = of(this.isListEmpty(events))
          this.paginationService.isIncrementEnabled(events)
        })
      ))
    );

What I have noticed is that using zip in ngOnInit() gets values until first char deletion, for example:

  • insert chars:
  • input: 'a' -> emit 'a'
  • input: 'ab' -> emit 'ab'
  • input: 'abc' -> emit 'avc'
  • remove 1 char:
  • input: 'ab' -> nothing emitted,
  • retry:
  • input: 'abc' -> nothing emitted,
Mateusz Gebroski
  • 1,274
  • 3
  • 26
  • 57
  • could u show the code for this.events$ – Fan Cheung Aug 23 '19 at 06:44
  • 2
    are both sources observables definitely emitting an initial value? Or has just 1 emitted, and `zip` is waiting for the other? Maybe `combineLatest` is more suitable? – Garth Mason Aug 23 '19 at 06:46
  • searchedEvent$ is input emitted from service, events$ is data from store fetched by selector – Mateusz Gebroski Aug 23 '19 at 07:09
  • @GarthMason combineLatest does not work also. – Mateusz Gebroski Aug 23 '19 at 07:17
  • 2
    I guess that for some reason ``this.events$ `` does not produce any value, is ``this.paginationService.page$`` an ``Subject`` or ``BehaviorSubject`` ? Try to ``tap`` before ``switchMap`` and log to see if this observable emits a value. Because the code inside ``switchMap`` is rather correct and most likely should emit so I'd say ``this.paginationService.page$`` is the culprit here. Could you eventually share the code of the service or at least parts with ``page$`` ? – Maksym Aug 23 '19 at 08:18
  • Hi Maksym. You are right! I've changed pagintationService to use BahaviourSubject instead of Subject and it works! This is an answer to my question. – Mateusz Gebroski Aug 23 '19 at 08:28
  • 1
    Ah! So zip was waiting for the value from `this.events$` ... same with `combineLatest` .. there was no latest value from `this.events$` so it didn't trigger – Garth Mason Aug 26 '19 at 00:49

0 Answers0