1

I have an array of Observable contained in activatedRoute.data.example and i want to subscribe to the latest value emitted.

private data$ = forkJoin(
  this.activatedRoute.data.pipe(
    map(({ examples }) => examples)
  )
);

ngOnInit(): void {
  this.data$.subscribe((v) => console.log(v));
}

Every example here is an http request:

this.http.get<Example>(`${this.baseUrl}`, { params: query })

But I never see neither the log nor the API call to the backend in the network browser's tab.

5
  • 3
    ForkJoin will not work in your case, it is emitting values, when the all of the passed observables will be completed. just remove it and try again. Commented Dec 22, 2021 at 12:22
  • Thank you very much. Another question if you have time: there is a way to determine whether all observables has completed? Commented Dec 22, 2021 at 13:43
  • When you subscribe to an observable there are 3 param functions. next, error, complete. You know that an subscription is completed when the complete function is been called. Commented Dec 22, 2021 at 15:01
  • Be aware that HTTP client auto completes the subscription when the HTTP call finishes, that is not usually happens with the other observables (router events, store subscriptions, etc...) Commented Dec 22, 2021 at 15:03
  • @StPaulis this is the difference of hot and cold observables. Commented Dec 22, 2021 at 15:20

3 Answers 3

1

map is an option, clearer way to do it with switchMap with from rxjs operators (you can also look for concatMap and mergeMap). So in the implementation, you can basically do:

  this.activatedRoute.data.pipe(
    map(({ examples }) => from(examples)),
    concatMap((examples) => examples)
  ).subscribe(...);

If that was not helpful, I'm attaching a Stackblitz link .

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

7 Comments

This is not really a realistic solution, it works in your stackBlitz because you are making use of of(), which is returning response there and then, but in real API has a travel delay, if you put a delay in your example, only the last response will ever get a response.
This is a mock solution. I don't think there'll be a difference in real world application. of() creates observable there, but it doesn't change code logic, we run our code logic on pipe(). It's independent of when observable is created. I rearranged the example for you. I added a mock delay, it still works: stackblitz.com/edit/angular-ivy-rv8bho?file=src/app/…
And also, at that moment he has the array of observables.
"Every example here is an http request", means example is an API Observable, you are placing the delay at the wrong place, try this [of(1).pipe(delay(1)), of(2)] you will get my point.
Yeah, you are right in that case switchMap returns immediately whenever one these observables complete. I thought he needed this. But if not, using concatMap instead of switchMap will solve the issue. See the the link: stackblitz.com/edit/angular-ivy-bdzwxh?file=src/app/…
|
0

map of rxjs is not same as 'map' of Array.

Rough example of show it should actually work:

private data$: Observable;

ngOnInit(): void {

  let getExample = (query) => this.http.get < Example > (`${this.baseUrl}`, {
    params: query
  });

  this.activatedRoute.data.subscribe(({ examples}) => { // if example is array 

    let obsArray: Observable[] = Object.entries(examples).map(([key, value] => getExample({
        [key]: value
      }));
      
      data$ = forkJoin(obsArray); 
      data$.subscribe(); // if needed
    });

}

Comments

0

I solved returning directly the forkJoin() of the Observables from the resolver, and than subscribing to that Observable throuhg a ReplaySubject

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.