angular - rxMethod on signal store dead after rxjs error - Stack Overflow

I'm using a ngrx signal store with rxMethod:export const MyStore = signalStore({ providedIn: 

I'm using a ngrx signal store with rxMethod:

export const MyStore = signalStore(
  { providedIn: 'root' },
  withState({ loading: false }),
  withMethods((state) => {
    const dataService = inject(DataService);

    return {
      loadMyData: rxMethod<void>(
        pipe(
          tap(() => patchState(state, { loading: true })),
          switchMap(() => dataService.loadDataFromApi()),
          catchError((error) => {
            console.error(error);
            return EMPTY;
          }),
          tap(() => patchState(state, { loading: false }))
        )
      ),
    };
  })
);

Now the used DataService throws or might fail:

@Injectable({
  providedIn: 'root',
})
export class DataService {
  loadDataFromApi() {
    return throwError(() => new Error('common data error'));
  }
}

I'm using MyStore.loadMyData() on a component

export class DetailsComponent {
  protected readonly store = inject(MyStore);
  readonly #trigger = signal<void>(undefined);

  constructor() {
    this.store.loadMyData(this.#trigger);
  }
}

After the first error occurred on loadMyData the rxMethod does not rerun again. Even if a new DetailsComponent instance if trying to access the in root provided store again.

I thought that the catchError on the store would have prevented this.

How can I make sure that my method is still functional even if an error occurs? How is error handling done properly in a rxMethod? Am I doing this the right way?

See StackBlitz example, where the error is only logged once to the console (no matter how often the details are opened/closed)

I'm using a ngrx signal store with rxMethod:

export const MyStore = signalStore(
  { providedIn: 'root' },
  withState({ loading: false }),
  withMethods((state) => {
    const dataService = inject(DataService);

    return {
      loadMyData: rxMethod<void>(
        pipe(
          tap(() => patchState(state, { loading: true })),
          switchMap(() => dataService.loadDataFromApi()),
          catchError((error) => {
            console.error(error);
            return EMPTY;
          }),
          tap(() => patchState(state, { loading: false }))
        )
      ),
    };
  })
);

Now the used DataService throws or might fail:

@Injectable({
  providedIn: 'root',
})
export class DataService {
  loadDataFromApi() {
    return throwError(() => new Error('common data error'));
  }
}

I'm using MyStore.loadMyData() on a component

export class DetailsComponent {
  protected readonly store = inject(MyStore);
  readonly #trigger = signal<void>(undefined);

  constructor() {
    this.store.loadMyData(this.#trigger);
  }
}

After the first error occurred on loadMyData the rxMethod does not rerun again. Even if a new DetailsComponent instance if trying to access the in root provided store again.

I thought that the catchError on the store would have prevented this.

How can I make sure that my method is still functional even if an error occurs? How is error handling done properly in a rxMethod? Am I doing this the right way?

See StackBlitz example, where the error is only logged once to the console (no matter how often the details are opened/closed)

Share Improve this question asked Mar 11 at 13:00 kerosenekerosene 90116 silver badges37 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

Handling the error using catchError and of inside the switchMap seems to not interrupt the stream from receiving changes.

export const MyStore = signalStore(
  { providedIn: 'root' },
  withState({ loading: false }),
  withMethods((state) => {
    const dataService = inject(DataService);

    return {
      loadMyData: rxMethod<void>(
        pipe(
          tap(() => {
            console.log('running');
            patchState(state, { loading: true });
          }),
          switchMap(() =>
            dataService.loadDataFromApi().pipe(    // <- changed here!
              catchError((error) => {              // <- changed here!
                return of(error);                  // <- changed here!
              })                                   // <- changed here!
            )                                      // <- changed here!
          ),
          tap(() => patchState(state, { loading: false }))
        )
      ),
    };
  })
);

Stackblitz Demo

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744793642a4594072.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信