0

I'm using Rxjs, and I want to create an Observable from the following pattern (in order):

  1. get params from paramMap$, then ...

  2. based on the value of params, get both (getData():Observable, getCategories():Observables) together, then ....

  3. from ([data, categories]) create the final object.

The code would look like:

//route = this.ActivatedRoute

let obs$ = route.paramMap.pipe(

// combineLatest() is not a pipable operator, so it shouldn't be used inside .pipe()
// also it doesn't accept a function,
// but this just to show you what I want to do.

combineLatest(params=>getData(params.id), params=>getCategories(params.id)),

map(([data, categories])=>{
//do some changes...
return {data,categories}
}
)
)

also where is the best place to put this code in Angular project:

  • constructor() is not the best practice, because this is a long-running operation (actually it has to do API requests)

  • ngOnInit() is not recommended, because in some point I have to change this.params which is used in the template

...
combineLatest(params=>
   getData(params.id).pipe(
        map(data=>{
            this.params.type=data.type; 
            return data
           })), 
   params=>getCategories(...) 
)

in template:

<div>{{params.type}}</div>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sh eldeeb
  • 1,589
  • 3
  • 18
  • 41
  • I didn't the second part of your question. > because in some point I should to change this.params whitch is used in the template, how does that affect doing this process in`ngOnInit()` – Ashish Ranjan May 06 '20 at 15:04
  • you cannot change a value used in the template after check completed, so moving this code to `ngOnInit` is not the best practice. @Ashish Ranjan – Sh eldeeb May 06 '20 at 19:38
  • I do not believe checks would be done on `ngOnInit()`, by this time even the view is not created. – Ashish Ranjan May 06 '20 at 19:41

1 Answers1

4

For piping the Observable after you get params, you can use switchMap and return a forkJoin() from within it.

this.route.paramMap.pipe(switchMap((params) => {
    return forkJoin(getData(params.id), getCategories(params.id));
}));

I believe, subscribing an Observable, doing API requests, all should ideally go to ngOnInit() unless you have some very specific requirement where you do not want these subscriptions when the component loads.

As far as this.params is concerned, you can assign this.params under either using a piped tap() or where you do a subscription for this Observable.

Ashish Ranjan
  • 12,760
  • 5
  • 27
  • 51