0

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;
    });
Atlas91
  • 5,754
  • 17
  • 69
  • 141

3 Answers3

2

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(
    ...
  );
}
ruth
  • 29,535
  • 4
  • 30
  • 57
  • I think that is the best answer but, I don't know why, the request is called 2 times. One with undefined params and the second one is correct. Of course if I check that params['param1'] is undefined the request not fires. Any idea? – Atlas91 Sep 17 '20 at 15:50
  • I still have this weird problem. I don't know why it tries to fires 2 requests – Atlas91 Sep 17 '20 at 15:54
1

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 })),
    );
  }
Chris
  • 2,117
  • 13
  • 18
0

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);
  }
Gopal
  • 603
  • 10
  • 18