Pavel
Pavel

Reputation: 2101

How to get rid from redundant request in Angular 6 service?

I have 3 independent places in my code which call VerificationService method getOrganizationView().

getOrganizationView(): Observable<any> {
  return this.httpClient.http.post(...)
}

First place is principal service:

@Injectable()
export class Principal {
   constructor(private verificationService: VerificationService) {}
   identity(force?: boolean): Promise<any> {
      return this.verificationService.getOrganizationView().toPromise().then((response ) => {
          ...
      })
   }
}

And one more service called LinkAccessService which do the same Principal that's not the point

And one more place is component:

export class VerificationComponent implements OnInit {
   constructor(private verificationService: VerificationService) {
   }

   ngOnInit() {
     this.verificationService.getOrganizationView()
       .subscribe((data: VerificationView) => {
         ...
     });
  }
}

And at loading app moment I had 3 calls instead single request, but these entities absolutely independent and I can't share data like between components directive and so on...

How traditionally in Angular 2+ resolve issue like this? I'm not mean distinct code for answer, I mean idea.

Upvotes: 2

Views: 374

Answers (3)

yurzui
yurzui

Reputation: 214007

The simplest way to cache your data is using shareReplay rxjs operator:

import { shareReplay } from 'rxjs/operators';

@Injectable()
export class VerificationService {
  organizationViewCache$: Observable<any>;

  getOrganizationView() {
    if (!this.organizationViewCache$) {
      this.organizationViewCache$ = this.http.get(...).pipe(shareReplay(1));
    }

    return this.organizationViewCache$;
  }
}

See also:

Upvotes: 3

DeborahK
DeborahK

Reputation: 60518

You could build a service that retrieves and caches the data. Any component that injects the service can then access that cached data without another request to the server.

export class ProductService {
    private productsUrl = 'api/products';
    products: IProduct[];

    getProducts(): Observable<IProduct> {
        // Returns the cached list if it exists.
        if (this.products) {
            return of(this.products);
        }
        return this.http.get<IProduct[]>(this.productsUrl)
                        .pipe(
                            tap(data => this.products = data),
                            catchError(this.handleError)
                        );
    }
}

There are several other answers, including using RxJS ReplaySubject here: What is the correct way to share the result of an Angular Http network call in RxJs 5?

Upvotes: 2

Jon
Jon

Reputation: 2671

I'm not 100% sure how your app is set up. But I would look into using an Event Emitter if I were you. You can have it emit an event, that your different components will listen to. Whichever component is supposed to make the call will make it appropriately and the others should not.

Upvotes: 0

Related Questions