Home > database >  Store value update change not detected on subscribe using NgRx component store in angular
Store value update change not detected on subscribe using NgRx component store in angular

Time:09-10

I am using NgRx component store in the angular application as below

export interface ProductCategoryState {
  categories: CategoryModel[];
  category: CategoryModel;
}

@Injectable()
export class ProductCategoryStore extends ComponentStore<ProductCategoryState> {
  constructor(private iGenericHttpClient: IGenericHttpClient<any>, private globalFacade: GlobalFacade) {
    super(initialState);
  }
readonly getCategories$: Observable<CategoryModel[]> = this.select((state) => state.categories);

  private readonly setCategories = this.updater((state, categories: CategoryModel[]) => ({
    ...state,
    categories: categories
  }));

  readonly delete = this.effect((id$: Observable<string>) => {
    return id$.pipe(
      withLatestFrom(this.getCategories$),
      switchMap(([id, categories]) => {
        return this.iGenericHttpClient.delete(`/category/${id}`).pipe(
          tapResponse(
            () => {
              const index = categories.findIndex((x) => x.id == id);
              categories.splice(index, 1);
              this.setCategories(categories);
            }
          )
        );
      })
    );
  });
}

On the delete operation, find the index and deleted the record, and update the state, however, the update is not detected on Subscribe in one of the components as shown below.

@Component({
  .......,
  providers: [ProductCategoryStore]
})
export class ProductCategoryComponent implements OnInit {
  constructor(private productCategoryStore: ProductCategoryStore) {}
  ngOnInit(): void {
    this.productCategoryStore.getCategories$.subscribe((dataSource) => {
      console.log(dataSource);
    });
  }
}

CodePudding user response:

I think you need to pass a new array to your update function. You are currently updating the existing array and passing the existing reference.

Try this:

const updatedCategories = categories.filter(x => x.id !== id);
this.setCategories(updatedCategories);

CodePudding user response:

I achieved the above by doing this

  private readonly deleteCategory = this.updater((state, id: string) => ({
    ...state,
    categories: state.categories.filter((category) => {
      if (category.id === id) return false;
      return true;
    })
  }));

And call as below

readonly delete = this.effect((id$: Observable<string>) => {
    return id$.pipe(
      switchMap((id) => {
        return this.iGenericHttpClient.delete(`/category/${id}`).pipe(
          tapResponse(
            () => {
              this.deleteCategory(id);
            },
          )
        );
      })
    );
  });
  • Related