Home > database >  Why shareReply() method is not working as expected - Angular 15
Why shareReply() method is not working as expected - Angular 15

Time:01-06

Trying to make use of same API in 3 components, In order to avoid duplicate HTTP calls I can use shareReply() to cache the response and use it where ever I want from RxJs. So I did like below

api-service.ts

getUsers(): Observable<any> {
    let headers = new HttpHeaders();
    headers = headers.set('app-id', '63b691428f53f6370fc9eed6');
    return this.http.get(this.url, { headers }).pipe(
      map((resp) => {
        return resp;
      }),
      shareReplay()
    );
  }

test1-component

data$!: Observable<any>;
  constructor(private api: ApiService) {}

  ngOnInit(): void {
    this.loadTest1Data();
  }

  loadTest1Data() {
    this.data$.subscribe({
      next: (response) => {
        console.log('Loading data for Component - 1', response);
      },
      error: (error) => {
        console.log('Error While Loading data for Component - 1', error);
      },
      complete: () => {
        console.log('Success');
      },
    });
  }

test2-component (test3-component also use same code)

data$!: Observable<any>;
  constructor(private api: ApiService) {}

  ngOnInit(): void {
    this.loadTest2Data();
  }

  loadTest2Data() {
    this.data$.subscribe({
      next: (response) => {
        console.log('Loading data for Component - 2', response);
      },
      error: (error) => {
        console.log('Error While Loading data for Component - 2', error);
      },
      complete: () => {
        console.log('Success');
      },
    });
  }

Error i got reproducing HERE - Stackblitz

Cannot read properties of undefined (reading 'subscribe')

Could someone tell me what went wrong and how to resolve it? or is there any other alternative approach is there? (apologies, I'm not allowed to use any third party state management tools)

Thanks in Advance for your valuable time

CodePudding user response:

Your test components aren't defining data$ so this.data$.subscribe is doing the equivalent of undefined.subscribe, hence the error.

For the test components you can do

@Input() data$: Observable<any> = of();

and pass in via

<app-test1 [data$]="data$"></app-test1>

Note, it's more common to do

<app-test1 [data]="data$ | async"></app-test1>

so that the components receive the data directly and the AsyncPipe takes care of subscribing and unsubscribing.

  • Related