Search code examples
angularrxjsangular-httpclient

How is it possible to return a predefined value from a http request, if the user is offline? (Angular)


I would like to cache some of the data, which is requested from the server. I modified the http request like this:

// user.ts
export class User {
    id: number;
    name: string;
}

// inside the component:

getUsers() : Observable<User[]> {
    return this.http.get<User[]>(this.api+'/get-users').pipe(
        tap(users => {
            localStorage.setItem("cache_users", JSON.stringify(users));
        })
    );
}

How is it possible to load the users from the cache, if the request failed, because the server was unreachable?


Solution

  • You could catch the error thrown once the request is made and return the cache, in case that the error was caused because of the client offline state:

    import {of, throwError } from 'rxjs';
    import {catchError} from 'rxjs/operators';
    import {HttpErrorResponse} from '@angular/common/http';
    
    getUsers() : Observable<User[]> {
        const url = `${this.api}/get-users`;
        return this.http.get<User[]>(url ).pipe(
            tap(users => localStorage.setItem(url , JSON.stringify(users))),
            catchError(error => {
              if(error instanceof HttpErrorResponse 
                 && error.status=== 0
                 && !error.url){
                 // See https://stackoverflow.com/a/14507670/5394220
                 // Try to read the local storage. If the key is not present, return an empty list
                 const rawJson = localStorage.getItem(url);
                 return of(!!rawJson ? JSON.parse(rawJson) : []);
              }
              // 
              return throwError(error);
            })
        );
    }
    

    You might want to try differents approach, for example using the window.navigator.onLine property.