Search code examples
javascriptangularjsstoreeffectsngrx

Angular - Loading data for a specific item with NGRX / Effects


I have a page with a list of products. These products reside in the store and are managed by a products reducer. A PRODUCTS.LOAD_ALL action is dispatched, an effect catches it, does an API call and dispatches a PRODUCTS.LOAD_ALL_SUCCESS action which the products reducer uses to populate the store.

I now have another page which is to edit a specific product and I have some questions regarding the best place to load / store this product. Should I stick with effects and dispatch an action to eventually get it in the store. If so, would I reuse the products reducer with an active property or would I introduce a new product reducer to hold this specific product? Alternative, should I step away form effects at this point and just call the API from my container component and pass the product down to the necessary children?


Solution

  • Should I stick with effects and dispatch an action to eventually get it in the store?

    Yes.

    Why?

    Because that way all your components can keep relying on the store and valid data. - Whenever the user is done editing, the following data-flow should happen:

    1. In your edit-component the used edits a copy of the product
    2. User clicks "Save" (or it's saved on input.blur, ect..)
    3. An action is dispatched with PRODUCTS.SAVE_PRODUCT
    4. An effect will call a service-method to persist the new changes (rest-call, or localstorage, ect..)
    5. When the persisting is successful -> the reducer gets an action with the new product-object and puts it into the store
    6. All components that are currently subscribing to store-updates will be informed automatically

    If so, would I reuse the products reducer with an active property or would I introduce a new product reducer to hold this specific product?

    If your products-array contains all the detail for all products already, I'd suggest to use the data from there - remember though: never edit store-data from the store directly, only work on copies (this can be enforced by using immutables, in case you are not doing that already)


    Alternative, should I step away form effects at this point and just call the API from my container component and pass the product down to the necessary children?

    Heeell no... I mean.. technically yes, you could - but you would loose practically all the benefits that the ngrx-store brings regarding clean data-flows, data-integrity, ect...

    Depending on the application(especially small ones) there are cases for sure where ngrx just mostly brings code-overhead and no real benefit - so there is no "one perfect way for all cases" - but I'd highly suggest not to go half way with a bunch of solutions that just messes up the code-base.