DataService that fetches data not loaded already or loads cached values I load an array from an API that is available throughout the user's whole session. This data is unlikely to change, so it can be cached safely. I have a DataService that works like this:


get data from the class property (scenario: going to a new route)
if nothing is there, get data from local storage (scenario: reload)
if nothing is there, fetch data from API (scenario: new session)


This is what I've come up with:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map, catchError, retry } from 'rxjs/operators';

@Injectable({
  providedIn: 'root',
})

export class DataService {
  protected data: Array&lt;any&gt; = null;

  constructor(private http: HttpClient) { }

  public getData(): Observable&lt;Array&lt;any&gt;&gt; {
    if (this.data === null) {
      this.data = JSON.parse(localStorage.getItem('data'));
  }

  if (this.datas !== null) {
    return of(this.data);
  }

  return this.http.get&lt;Object&gt;(this.url + this.route).pipe(
    retry(3),
    map(response =&gt; {
      this.data = response as Array&lt;any&gt;;
      localStorage.setItem('data', JSON.stringify(this.data));
      return this.data;
    }),
    catchError(error =&gt; {
      this.handleError(error);
      return [];
    })
  );
}


The service is registered in the app.component.ts and used like this in other components:

import { Component, OnInit } from '@angular/core';
import { DataService } from 'src/app/service/data.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.less'],
  providers: []
})

export class ExampleComponent implements OnInit {
  protected subscribers: Subscription[] = [];

  public data: Array&lt;any&gt; = [];

  constructor(public data: DataService) { }

  ngOnInit() {
    this.subscribers.push(
      this.data.getData().subscribe((data) =&gt; { this.data = data })
    );
  }

  ngOnDestroy() {
    for (let subscriber of this.subscribers) {
      subscriber.unsubscribe();
    }
  }
}


Is it a good approach? Is this "the Angular way"? Can it be improved? Is it readable? Does this indeed increase performance? At least it uses fewer HTTP requests.

This class is shortened a bit for the review, so don't worry that there's no handleError method.
Short review

  if (this.datas !== null) {
    return of(this.data);
  }


That looks like a bug, should it not be (this.data !== null) ?

Also, what is of, where is it defined?

Other than, the code is very clean in both parts. So clean, that I almost would switch the of and the localStorage call. But since this would dupe the null check, that might in the end not be the best idea.

  if (this.data !== null) {
    return of(this.data);
  } else {
      this.data = JSON.parse(localStorage.getItem('data'));
      if (this.data !== null) {
        return of(this.data);
      }
  }