Angular get query param and call service

5.3k Views Asked by At

I've got a problem in my angular app. I have to call a service reading some params from url. It's not working because the service is fired before the subscription to have the params is finished. In my service file I have this:

constructor(private http: HttpClient, private route: ActivatedRoute) { 
    this.route.queryParams.subscribe(params => {
      this.param1 = params['param1'];
      this.param2 = params['param2'];
    });
  }

and then the service:

getConfigs() {
    let configPath = baseUrl + this.param1 + "/" + this.param2;
    return this.http.get<any>(configPath);
  }

so, in my AppComponent I call the getConfigs() service but it's not working because the two params are undefined. How can I fix it? That's how I call the service in AppComponent

this.service.getConfigs().subscribe((configData) => {
      this.configParams = configData;
    });
3

There are 3 best solutions below

3
On BEST ANSWER

Take the query parameters from router, and use the first() operator to get only the first event and then use switchMap() to get the data with params option.

  constructor(
    private _http: HttpClient,
    private _route: ActivatedRoute,
  ) { }

  getConfigs() {
    return this._route.queryParams.pipe(
      // rxjs operator skip empty object
      filter(params => !!Object.keys(params).length),
      // rxjs operator use only first event
      first(),
      // rxjs operator switch to another observable
      switchMap(params => this._http.get('host', { params })),
    );
  }
0
On

you need to pass values to the service.

this.service.getConfigs(this.param1, this.param2).subscribe((configData) => {
      this.configParams = configData;
});

getConfigs(param1, param2) {
    let configPath = baseUrl + param1 + "/" + param2;
    return this.http.get<any>(configPath);
  }
2
On

You could use a RxJS higher order mapping operator like switchMap to chain co-dependent observables. Try the following

constructor(private http: HttpClient, private route: ActivatedRoute) { }

getConfigs() {
  return this.route.queryParams.pipe(
    switchMap(params => {
      let configPath = baseUrl + params['param1'] + "/" + params['param2'];
      return this.http.get<any>(configPath);
    })
  );
}

Although I'd say it's better to get the route params in the component instead of the service. So you could do something like the following

Service

constructor(private http: HttpClient) { }

getConfigs(param1: any, param2: any) {
  const configPath = baseUrl + param1 + '/' + param2;
  return this.http.get<any>(configPath);
}

Component

constructor(private someService: SomeService, private route: ActivatedRoute) { }

ngOnInit() {
  this.route.queryParams.pipe(
    switchMap(params => this.someService.getConfigs(params['param1'], params['param2']))
  ).subscribe(
    ...
  );
}