Wait for localstorage inside http observable?

Hey guys,
i’m fairly new to observables and i’m currently trying to change some code to understand the concept as a whole.
However, i came across a problem. I want to access my API using the http observable.

return this.http.get(BACKEND_URL + '/api/ROUTE', {
   headers: headers,
   params: params,
   observe: 'response'
}).pipe(map(response => {
   this.localStorage.setEtag(response.headers.get('etag'));
 }));

Before that, i want to add a header containing the last etag, which will get saved into local storage after fetching the data.
l

let headers = new HttpHeaders()
   .append('accept-language', localLanguage);
if (etag != null)
   headers = headers.append('If-None-Match', etag);

Now my problem lies within receiving the saved etag and waiting for it, since it is asynchonous.

let etag = '';
this.localStorage.getEtag()
   .then(data => {
      etag = data;
});

How can i wait for the local storage to complete in order to actually append it to the headers? The local storage returns as far as i know a promise of the value. For that reason i would like to (And had it prior to the observables) that i just await the etag and then append it into the headers. However, since this new method returns the observable i can’t await it since it would turn the return type to a promise.
I don’t know, if this whole approach is wrong at its core, i would appreciate some help.

Here is the full request method:

    public getInstances(): Observable<any> {
        let etag = '';
        this.localStorage.getEtagInstances()
            .then(data => {
                etag = data;
            });

        let headers = new HttpHeaders()
            .append('accept-language', localLanguage);
        if (etag != null)
            headers = headers.append('If-None-Match', etag);
        return this.http.get(BACKEND_URL + '/api/ROUTE', {
            headers: headers,
            params: params,
            observe: 'response'
        }).pipe(map(response => {
            this.localStorage.setEtagInstances(response.headers.get('etag'))
        }))
    }
interface Instance {
  // don't know what goes here, but don't want to perpetuate `any` abuse
}

getInstances(): Observable<Instance[]> {
  return from(this.localStorage.getEtagInstances()).pipe(
    switchMap(etag => {
      let headers = new HttpHeaders().append("accept-language", localLanguage);
      if (etag) { // i avoid direct comparison against null as much as possible
        headers = headers.append("If-None-Match", etag);
      }
      return this.http.get<Instance[]>(BACKEND_URL + "/api/ROUTE", 
        {headers, params, observe: "response"});
    }),
    tap(rsp => this.localStorage.setEtagInstances(rsp.headers.get("etag")))
  );
}
2 Likes