Utilizing NgRx 8 Actions in Conjunction with NgRx 7 Reducers: An Implementation

In the development of my new Angular 8 project, I have incorporated the NgRx library. It was mentioned to me that actions are created using createAction in NgRx 8, but reducers are built using NgRx 7. Initially, I implemented my reducer with NgRx 8, but now I need to switch to NgRx 7. Below are the actions and reducer I have:

book.actions.ts

import { createAction, props } from "@ngrx/store";
import { Book } from "./book";

export const BeginGetBooksAction = createAction("BeginGetBooks");

export const SuccessGetBooksAction = createAction(
  "SuccessGetBooks",
  props<{ payload: Book[] }>()
);

export const BeginAddBookAction = createAction(
  "BeginAddBook",
  props<{ payload: Book }>()
);

export const SuccessAddBookAction = createAction(
  "SuccessAddBook",
  props<{ payload: Book[] }>()
);

book.reducer.ts

import { Action, createReducer, on } from "@ngrx/store";
import * as BooksActions from "./book.action";
import { Book } from "./book";

export interface BooksState {
  Books: Book[];
  ReadBooks: { book: Book; addedOn: Date }[];
  WantToReadBooks: { book: Book; addedOn: Date }[];
  editBook: Book;
}

const initialState: BooksState = {
  Books: [],
  ReadBooks: [],
  WantToReadBooks: [],
  editBook: new Book()
};

export function booksReducer(state = initialState, action: Action) {
  switch (action.type) {
    case BooksActions.BeginGetBooksAction.type:
      return state;

    case BooksActions.SuccessGetBooksAction.type:
      return { ...state, Books: action.payload };

    case BooksActions.BeginAddBookAction.type:
        return state;

    case BooksActions.SuccessAddBookAction.type:
        return { ...state, Books: action.payload };

    default:
      return state;
  }
}

An error is being triggered for action.payload

Property 'payload' does not exist on type 'Action'.

Can anyone pinpoint where I may have gone wrong??

Answer №1

I penned a comparison in a blog post on the topic of NgRx creator functions 101.

The post showcases a blend of syntax from two different versions:

export const addToCart = createAction(
  // defining action type
  '[Product List] Add to cart',
  // optional payload
  props<{ sku: string }>(),
)
export const removeFromCart = createAction(
  // defining action type
  '[Product List] Remove from cart',
  // optional payload
  props<{ sku: string }>(),
)

export function reducer(
  state = initialState,
  action: ReturnType<typeof addToCart> | ReturnType<typeof removeFromCart>,
) {
  switch (action.type) {
    case addToCart.type:
      return {
        ...state,
        cartItems: {
          ...state.cartItems,
          [action.sku]: (state.cartItems[action.sku] || 0) + 1,
        },
      }

    case removeFromCart.type:
      return {
        ...state,
        cartItems: {
          ...state.cartItems,
          [action.sku]: Math.max((state.cartItems[action.sku] || 0) - 1, 0),
        },
      }

    default:
      return state
  }
}

Answer №2

While your reducer is effective, the issue lies within your type definition. You are utilizing a simple Action type which lacks the presence of a payload. Consider exploring alternative type definitions such as any or experimenting with union types. However, in the case of union types, ensure that you have all necessary named imports from the action file. I suggest delving into the next generation syntax of reducers as it may provide a more suitable solution for your situation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Changing the Month Label Format from Short (MMM) to Long (MMMM) in Angular Material Datepicker

I am looking to customize the month labels in Angular Material datepicker. By default, the month view displays in MMM format and I want to change it to MMMM using custom MatDateFormats. export const APP_DATE_FORMATS: MatDateFormats = { parse: { dat ...

Sample Angular component showcasing arguments and content within a storybook MDX preview

We showcase our angular components using Storybook and typically utilize the MDX format for this purpose When dealing with an angular component that needs content and accepts properties (via the "Controls" Plugin), I am facing difficulties in implementing ...

Unable to store the outcomes from [ngbTypeahead] in [resultTemplate]

I'm trying to integrate ngbTypeahead into my HTML using the code snippet below <ng-template #rt let-r="result" let-t="term"> <ngb-highlight [result]="r.FirstName" [term]="t"></ngb-highlight> </ng-template> <input name ...

What is causing the error message "Module '@reduxjs/toolkit' or its type declarations are not found" to appear?

Although I have a good understanding of React-Redux, I decided to delve into TypeScript for further practice. Following the recommended approach from the react-redux team, I created a new project using the TS template: "npx degit reduxjs/redux-templa ...

What is the best way to locate and access a JSON file that is relative to the module I am currently working

I am in the process of creating a package named PackageA, which includes a function called parseJson. This function is designed to accept a file path pointing to a JSON file that needs to be parsed. Now, in another package - PackageB, I would like to invok ...

Experimenting with throws using Jest

One of the functions I'm testing is shown below: export const createContext = async (context: any) => { const authContext = await AuthGQL(context) console.log(authContext) if(authContext.isAuth === false) throw 'UNAUTHORIZED' retu ...

Utilize ngrx/store to capture events from various components within an Angular application

Is there a way to utilize ngrx store in Angular to capture events from a grandchild component without relying on a service, Behavior Subject, or @Output? ...

AngularJS2 brings a powerful and seamless implementation of indexedDB for efficient

I'm on the hunt for an indexeddb implementation that works seamlessly with Angularjs2. While I stumbled upon this api at https://github.com/gilf/angular2-indexeddb, it appears to be lacking in active development and may not be ready for production use ...

Protractor typescript guide: Clicking an element with _ngcontent and a span containing buttontext

I'm struggling with creating a protractor TypeScript code to click a button with _ngcontent and span buttontext. Does anyone have any ideas on how to achieve this? The code snippet on the site is: <span _ngcontent-c6 class="braeting net-subheadi ...

Svelte: highlighting input text when selected

Is there a way to select the text of an input element when it is focused using bind:this={ref} and then ref.select()? It seems to only work when I remove the bind:value from the input element. Why is that the case, and how can I solve this issue? Thank yo ...

Integrating meta tags into Angular Universal through subscription

I am facing challenges with dynamically setting meta tags in my Angular application. I am able to set the tags in the ngOnInit method without any issues, but when I try to use a Subscription, the addTag method doesn't work as expected. export class Ap ...

Tips for extracting a specific segment from a URL string

Take a look at the outcome of the console.log below: console.log('subscribe:', event.url); "https://hooks.stripe.com/adapter/ideal/redirect/complete/src_1E2lmZHazFCzVZTmhYOsoZbg/src_client_secret_EVnN8bitF0wDIe6XGcZTThYZ?success=true" I need to ...

Disabling Immediate Row Checkbox in Angular Datatable Based on Column Data

Is there a way to prevent the checkbox in a row from being checked based on certain column data? In my datatable, I need to implement a condition where if firstname="Superman", then the checkbox for that particular row should be disabled to preve ...

What is the best way to address dynamic meta tags in Angular server-side rendering (SSR

My Angular application uses server side rendering, and I am dynamically loading the meta tags content from the backend. Despite seeing the proper content in the HTML, Facebook's debugger does not seem to recognize the tags. Has anyone else encountered ...

Exploring TypeScript's Conditional Types

Consider this scenario: type TypeMapping = { Boolean: boolean, String: string, Number: number, ArrayOfString: Array<string>, ArrayOfBoolean: Array<boolean> } export interface ElemType { foo: keyof TypeMapping, default: valueof T ...

Guide to retrieving static information for forms with the use of reactive forms

I am encountering an issue with my reactive form. When I click the new button, a duplicate section appears but the options in the select field are not visible. Additionally, I receive errors as soon as the page loads: ERROR Error: Cannot find control with ...

Incorporating essential npm packages into an Angular2 project

Lately, I integrated the ngx-bootstrap component into an Angular project that my team has been collaborating on. I'm facing a challenge in having to individually instruct team members to run npm install ngx-bootstrap --save to install the component l ...

Issue with Domsanitizer bypasssecuritytruststyle functionality on Internet Explorer 11 not resolving

CSS:- Implementing the style property from modalStyle in TypeScript <div class="modal" tabindex="1000" [style]="modalStyle" > Angular Component:- Using DomSanitizer to adjust height, display, and min-height properties. While this configuration work ...

Utilizing JavaScript's Array.sort() method for sorting objects with varying properties

Currently, I am dealing with these specific Objects: let obj1 = { from: Date, to: Date } let obj2 = { date: Date } These Objects have been placed in an Array: let arr = [ obj1, obj2 ] My goal is to organize the objects within the array by using arr.sort( ...

When working with Angular and NGRX, I often wonder if opening my app in multiple tabs within the same browser will result in all tabs pointing to a single NGRX instance

Is it possible to access my localhost:9000 in multiple tabs? If I open it in 3 tabs, will all those 3 tabs point to a single NGRX instance or will each tab of localhost have its dedicated NGRX instance? I haven't had the chance to test this yet. ...