0

The user can load companies by id via a CompanyService. As the company will not change throughout the life time of the application, I thought it would make sense to cache all already loaded items and load new ones only if needed.

Now I came up with this solution that works using an local Array<Company> as the cache. It returns of() of a found elment and alternativley loads a new one and stores it in the cache.

export class CompanyService {
  private cache: Array<Company> = [];
  private path: string = '';

  getById(id: number): Observable<Company> {
    const company = this.cache.find(item => item.id === id);

    if (company) {
      return of(company);
    }

    return this.http.get<any>(this.path + id).pipe(
      map(response => {
        this.cache.push(response);
        return response;
      }),
      catchError(error => {
        return of(null);
      })
    );
  }
}

Is this the right way to do it?

I thought it might be better to use something like:

private cache$: Observable<Array<Company>>;

But I don't know:

  • … whether this is a better approach?
  • … how to add a new item?
  • … how find an item in this Observable and return a new one otherwise?
lampshade
  • 2,470
  • 3
  • 36
  • 74
  • This could help you: https://stackoverflow.com/a/53260507/12193298 – Jeroenouw Apr 29 '20 at 08:22
  • Yes, so the components are using the service? then it is better to use the observable approach. and then with emit you can pass the values. –  Apr 29 '20 at 08:24
  • @savantTheCoder Yes, Components use the service. That's why I thought the Obersavble approach would be better, as you endorse. – lampshade Apr 29 '20 at 08:26
  • Yes, I put it as a ans ware. you can vote on it, if that is the solution. –  Apr 29 '20 at 08:28

1 Answers1

0

What I'd do is: providing this service in root, first of all. Start with returning observable if it needs to return one.

@Injectable({
  providedIn: 'root'
})
export class CompanyService {
  private cache:Company[] = [];
  private path: string = '';

  getById(id: number): Observable<Company> {
    return new Observable(subs=>{
      const company = this.cache.find(item => item.id === id);
      if(!company){
        this.http.get<Company>(this.path + id).subscribe(result=>{
          this.cache.push(result);
          subs.next(result);
        });
      } else {
        subs.next(company);
      }
    });
  }
}

You might need to implement null check and handle errors. I hope you'll find it helpful.

  • Thanks for your answer. Could yuo explain what the difference to the current solution is? It seems, that it is doing the same thing a bit more complicated. – lampshade Apr 29 '20 at 10:14