0

I'm working in angular 4 and I have an appConfigService that provides the url of the api application from an settings.json file, something like:

private appConfig: AppConfig;

constructor(private http: Http) {
    this.loadConfig().subscribe(e => this.appConfig = e);
}
public loadConfig(): Observable<AppConfig> {
    return this.http
      .get("appsettings.json")
      .map(this.mapAppConfig)
      .catch(this.handleError);
}

then i use that url for all my following requests.

it work fine for requests sent after the url has been returned, however I am having issues with the requests sent when the page loads (and the url has not been retrieved yet).

I am aware I can use the flatmap function in the services that load at the startup but i find myself creating basically two implementations of the same function:

private getBasicRequest(offset: number = 0, limit:number = 0 ): Observable<Response>{
    if (!this.appConfigService.isAppConfigValid()) {
      var urlObserver = this.appConfigService.loadConfig();

      var request = urlObserver
        .flatMap(responseFromConfigService =>
          this.http.get(responseFromConfigService.apiBaseAddress + "/entries/" + this.searchTerm + "?offset=" + offset + "&limit=" + limit));

      return request;

    } else {
      var url = this.appConfigService.getApiLink("entries/" + this.searchTerm + "?offset=" + offset + "&limit=" + limit);
      return this.http.get(url);
    }
  }

What would be a better way to deal with this scenario? I tried to get the appConfigService service to start at 'startup' that would fix my issue but it didn't work.

Faz
  • 61
  • 6
  • You can use https://stackoverflow.com/questions/37611549/how-to-pass-parameters-rendered-from-backend-to-angular2-bootstrap-method/37611614#37611614 or https://stackoverflow.com/questions/36271899/what-is-the-correct-way-to-share-the-result-of-an-angular-2-http-network-call-in/36291681#36291681 – Günter Zöchbauer Aug 29 '17 at 08:26

1 Answers1

1

Always use the observable instead of subscribing them. Your config service should look like this:

export class AppConfigService
{
    public config$: Observable<AppConfig>;

    constructor(private http: Http) {
      this.config$ = this.http
          .get("appsettings.json")
          .map(this.mapAppConfig)
          .catch(this.handleError)
          .share();
    }
}

And all other services are using it like this:

private getBasicRequest(offset = 0, limit = 0): Observable<Response> {
      var config$ = this.appConfigService.config$;

      var request = config$
        .map(config => config.apiBaseAddress)
        .map(base => `${base}/entries/${this.searchTerm}?offset=${offset}&limit=${limit})
        .flatMap(url => this.http.get(url));

      return request;
  }
Markus Kollers
  • 3,508
  • 1
  • 13
  • 17
  • 1
    Thanks for the answer! I tried this way but the issue is that I end up requesting the appsettings.json at every request, I just want to request it once, it just contains one url and that's the one that is used everywhere in the application. – Faz Aug 29 '17 at 08:33
  • Thanks that worked, but is there a way to avoid having to use a flatmap in all the other requests? In the appsettings.json I have the basic api url, therefore I use that everywhere and it's a bit annoying to use the flatmap everywhere. – Faz Sep 12 '17 at 07:41