Atlas91
Atlas91

Reputation: 5904

Angular get query param and call service

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;
    });

Upvotes: 0

Views: 6539

Answers (3)

Chris
Chris

Reputation: 2427

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 })),
    );
  }

Upvotes: 1

Barremian
Barremian

Reputation: 31135

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(
    ...
  );
}

Upvotes: 2

Gopal
Gopal

Reputation: 673

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);
  }

Upvotes: 0

Related Questions