angularangular-akitaakita

akita angular selectQuery catch 404


I'm investigating on an alternative to NgRx. And so far Akita is a good bet but I'm struggling with error managing. Sometimes I want an error to be app wide and sometimes I want it to be managed by a component. In the example below I launch a 404 error and I want my component to be aware of this and act accordingly but I can't figure out how. Can you help ?

DummyService (Akita):

 get(id: number) {
    this.dummyService.loadByID(id).then((dummy: Dummy) => {
      this.akitaDummyStore.setDummy(dummy);
    })/*.catch((err) => {
      alert(err);
      Here it's working I go inside catch but I don't want it here I want the catch in the component
    })*/;
  }

Component :

  constructor(
    private akitaDummyQuery: AkitaDummyQuery,
    private akitaDummyService: AkitaDummyService
  ) {
  }

  ngOnInit() {

    this.akitaDummyQuery.selectEntity(666).subscribe(
      akDummy => {
        if (!akDummy) {
          this.akitaDummyService.get(666);
          return;
        }
        this.dummy= Dummy.parse(akDummy.result);
      },
      error => {
        //here I would like to catch the error in the component in order to display a component level error message. 
        alert(error);
      }
    );
  }

}

I can handle the error like this :

this.akitaDummyQuery.selectEntity(id).subscribe(
  akDummy => {
    if (!akDummy) {
      this.akitaDummyService.get(id).catch(err => {
        if (err.statusText === 'Not Found') {

        }
      });
      return;
    }
    this.dummy = Dummy.parse(akDummy.result);
  });

But when I do this the akita redux object stays in "loading" state = true


Solution

  • Thank's to @NetanelBasal I was able to solve my issue, I was doing everything the wrong way :

    the akita service

    export class AkitaDummyService {
      constructor(private akitaDummyStore: AkitaDummyStore, private dummyService: DummyService) {
      }
      get(id: number) {
        return this.dummyService.get(id).pipe(tap((dummy) => this.akitaDummyStore.add(createAkitaDummy(dummy.data))));
      }
    }
    

    the akita query

    export class AkitaDummyQuery extends QueryEntity<AkitaDummyState, AkitaDummy> {
    
      constructor(protected store: AkitaDummyStore) {
        super(store);
      }
    
      selectEntity<R>(id: getIDType<AkitaDummyState>): Observable<Dummy | any> {
        return super.selectEntity(id).pipe(filter(dummy => !!dummy), map((dummy: AkitaDummy) => Dummy.parse(dummy)));
      }
    
    }
    

    the component

    export class PageDummyComponent implements OnInit {
      dummy: Dummy;
    
      constructor(
        private akitaDummyQuery: AkitaDummyQuery,
        private akitaDummyService: AkitaDummyService
      ) {
      }
    
      ngOnInit() {
        this.loadDummy(5);
      }
    
    
      loadDummy(id) {
        if (!this.akitaDummyQuery.hasEntity(id)) {
          this.akitaDummyService.get(id).subscribe({
            error: (err) => {
              // when 404 do something
    
            }
          });
        }
        this.akitaDummyQuery.selectEntity(id).subscribe(dummy => this.dummy = dummy);
      }
    }