angulartypescriptngrxangular8angular-ngrx-data

NgRx Data - How to hook into a addOne success Action in a typesafe way?


I'm new to @ngrx/data and I'm going through the documentation.

Using the guide I've been able to replicate what I've previously done manually - for example using the service on this overview page, the following works calling REST-API and adding supplier to store.

component.ts

  onSave(supplier: Supplier) {
    this.supplierService.add(supplier);
  }

I know for the effect I can do the following:

  hello$ = createEffect(
    () =>
      this.actions$.pipe(
        ofType('[Supplier] @ngrx/data/save/add-one/success'),
        tap(console.log)
      ),
    { dispatch: false }
  );

BUT - is there a type-safe way to hook into a success API call action / entity actions in general?

Update - clarification

I'm using @ngrx/data and so I'm not creating the actions directly myself along with the export of types.

Upon successful addition of a supplier - which after http call results in an action with type: '[Supplier] @ngrx/data/save/add-one/success' - I want to perform an effect. Rather than use the string '[Supplier] @ngrx/data/save/add-one/success' (shown above) is there a type safe hook?

Previously (when creating the actions myself) I would export a union type and do ofType(supplierActions.addSupplier)

Update - closer to an answer

Found ofEntityType and ofEntityOp which gets me closer to my aim as these work like ofType:

  hello$ = createEffect(
    () =>
      this.actions$.pipe(
        ofEntityType('Supplier'),
        ofEntityOp(EntityOp.SAVE_ADD_ONE_SUCCESS),
        tap(console.log)
      ),
    { dispatch: false }
  );

Now to just find a way of typing 'Supplier' from the entityMetadata

const entityMetadata: EntityMetadataMap = {
  Supplier: {}
};

Solution

  • You can do something like this:

    let array = Object.keys(entityConfig.entityMetadata);
    

    it will return the name of your entities, in this case “Supplier”. then just use the array as parameter for ofEntityType

    hello$ = createEffect(
        () =>
          this.actions$.pipe(
            ofEntityType(array),
            ofEntityOp(EntityOp.SAVE_ADD_ONE_SUCCESS),
            tap(console.log)
          ),
        { dispatch: false }
      );