Issue in NGRX reducer: The argument "X" cannot be assigned to the parameter of type "Y"

Following a successful compilation of an Angular app build with ngrx, I encountered an error.

ERROR in src/app/store/cart-items.reducer.ts:17:62 - error TS2345: Argument of type '{ items: CartItem[]; bestCommercialOfferValue: number; }' is not assignable to parameter of type 'CartItemsState'.
  Property 'commercialOffers' is missing in type '{ items: CartItem[]; bestCommercialOfferValue: number; }' but required in type 'CartItemsState'.

17     on(DeleteCartItem, (state, action) => (deleteReturnState(state, action.isbn))),
                                                                ~~~~~

  src/app/store/cartItemsState.ts:7:5
    7     commercialOffers: CommercialOffer[];
          ~~~~~~~~~~~~~~~~
    'commercialOffers' is declared here.
src/app/store/cart-items.reducer.ts:18:73 - error TS2345: Argument of type '{ items: CartItem[]; bestCommercialOfferValue: number; }' is not assignable to parameter of type 'CartItemsState'.

18     on(UpdateQuantityToBuyCartItem, (state, action) => (GetUpdatedState(state, action.cartItem))),
                                                                           ~~~~~

The above error is specific to the reducer file named cart-item.reducer.ts. This error occurred after adding a field called commercialOffers to the state object.

import { CartItem } from '../models/cartItem';
import { CommercialOffer } from '../models/commercialOffer';

export interface CartItemsState {
    items: CartItem[];
    bestCommercialOfferValue: number;
    commercialOffers: CommercialOffer[];
}

The content of the concerned reducer file is as follows :

import { Action, createReducer, on } from '@ngrx/store';
import { CartItem } from '../models/cartItem';
import { CommercialOffer } from '../models/commercialOffer';
import { AddCartItem, DeleteCartItem, UpdateQuantityToBuyCartItem, ClearCart, ApiGetCommercialOffersSuccess } from './actions';
import { CartItemsState } from './cartItemsState';


export const initialState: CartItemsState = {
    items: [],
    bestCommercialOfferValue: 0,
    commercialOffers: []
};

const _cartItemsReducer = createReducer(
    initialState,
    on(AddCartItem, (state, action) => ({ items: [...state.items, action.data], bestCommercialOfferValue: state.bestCommercialOfferValue })),
    on(DeleteCartItem, (state, action) => (deleteReturnState(state, action.isbn))),
    on(UpdateQuantityToBuyCartItem, (state, action) => (GetUpdatedState(state, action.cartItem))),
    on(ClearCart, (state, action) => ({ items: [], bestCommercialOfferValue: 0, commercialOffers: [] })),
    on(ApiGetCommercialOffersSuccess, (state, action) => ({ items: state.items, bestCommercialOfferValue: getBestCommercialOffer(state.items, action.commercialOffers) }));

function getBestCommercialOffer(actualCartItems: CartItem[], bunchOfCommercialOffers: CommercialOffer[]): number {

const subTotal = actualCartItems.reduce((sum, current) => sum + current.bookInfos.price * current.quantityToBuy, 0);
const reductionValues: number[] = [];

bunchOfCommercialOffers.forEach(actualCommercialOffer => {
    if (actualCommercialOffer.type == "percentage") {
        reductionValues.push(actualCommercialOffer.value);
    } else if (actualCommercialOffer.type == "minus") {
        reductionValues.push(actualCommercialOffer.value);
    } else if (actualCommercialOffer.type == "slice") {
        const sliceValue = actualCommercialOffer.sliceValue;
        const reductionValue = actualCommercialOffer.value;
        const multiply = Math.trunc(subTotal / sliceValue);

        reductionValues.push(reductionValue * multiply);
    }});

    return reductionValues.reduce((previousValue, actualValue) => previousValue = previousValue > actualValue ? previousValue : actualValue, 0);}


function deleteReturnState(actualCartItemsState: CartItemsState, isbn: string): CartItemsState {
    return {
        items: actualCartItemsState.items.filter(item => item.bookInfos.isbn != isbn),
        bestCommercialOfferValue: actualCartItemsState.bestCommercialOfferValue,
        commercialOffers: actualCartItemsState.commercialOffers
    }
}

function GetUpdatedState(actualCartItemsState: CartItemsState, cartItemToUpdate: CartItem): CartItemsState {
    const newList: CartItem[] = [];

    actualCartItemsState.items.forEach(cartItem => {

    const newCartItem = <CartItem>{
        bookInfos: cartItem.bookInfos,
        quantityToBuy: cartItem.quantityToBuy
    }

    if (cartItem.bookInfos.isbn == cartItemToUpdate.bookInfos.isbn) {
        newCartItem.quantityToBuy = cartItemToUpdate.quantityToBuy;
    }

    newList.push(newCartItem)})

    return {
        items: newList,
        bestCommercialOfferValue: actualCartItemsState.bestCommercialOfferValue,
        commercialOffers: actualCartItemsState.commercialOffers
    }}

export function cartItemsReducer(state: CartItemsState | undefined, action: Action) {
    return _cartItemsReducer(state, action);
}

Interestingly, despite this error, my application continues to run perfectly well.

Answer №1

It appears that you have included the parameter commercialOffers in your action. To resolve the error, be sure to include this property in your object. Alternatively, if the parameter is not required, you can define your interface as shown below:

export const initialState: CartItemsState = {
    items: [],
    bestCommercialOfferValue: 0,
    commercialOffers?: []
};

Notice the presence of ? in commercialOffers?: [], indicating that this parameter is optional.

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

Click on a hyperlink to open a fresh page in a separate tab using Google Chrome

Is there a way to open a link in a new tab instead of a new window on ajax success in Chrome using jQuery or JavaScript? Here is the code snippet: $("#A1").click(function (event) { $.ajax({ type: "POST", url: "Home.aspx/btnTestProje ...

Convert image file to a React TypeScript module for export

Imagine a scenario where you have a folder containing an image file and an index file serving as a public API. Is there a method to rename the image file before reexporting it? Here is the structure of the folder: └── assets/ ├── index.t ...

Passing a variety of values from child to parent component in Angular through a unified function

Utilizing a checkbox-component within a parent component, I have implemented an @Output() to notify the parent component when the value changes. While my code is currently functional, using the checkbox-component multiple times throughout my project has l ...

Check the row in a JQuery table by using the .on("click") function to determine if a hyperlink within the row was clicked or if

I am in the process of building a website using the following libraries: Parse.js: 1.4.2 JQuery: 1.11.2 and 1.10.3 (U.I.) Twitter Bootstrap: 3.3.4 To demonstrate what I am trying to achieve, I have set up this JSfiddle with placeholder data: https://jsf ...

Sending updated data from modal back to child component

Within my parent component, I have two child components: Child0 and Display. Child 0 consists of a single button that triggers the opening of a modal where users can select items from a list. The Display component, on the other hand, only contains a label ...

Transferring numerous hefty JSON documents at once from React Native to Node.js

I am facing a challenge while attempting to upload multiple large JSON files from React-native to Node.js. The files are successfully uploaded, except for when the file size is large, causing it not to upload in one attempt. My suspicion is that: Due t ...

Animation for Contact Forms

Here is the code snippet I am working with: input[type=text], [type=email], select, textarea { width: 100%; padding: 12px; border: 1px solid #555; margin-top: 6px; margin-bottom: 16px; resize: vertical; } input[type=submit] { background ...

Tips for using AJAX and JSON to maintain real-time data in JSP pages

After hours of searching, I still couldn't find a simple solution to my problem. I need to make something easy. I have a Java class that contains a map of "Service" objects along with an integer variable called "lastCustomer". When this value changes ...

Unable to establish proper functionality of username variables in Node.js chat application

For my latest project, I am developing a chat application in node.js following a tutorial from socket.io. The main objective of the app is to allow users to input their username along with a message, which will then be displayed as "username: message" in t ...

Adjust the height of images to be consistent

I'm currently working on creating a grid layout with 4 images in a row using DaisyUI card component. However, I've run into an issue where there is white space at the bottom of some images due to varying image heights. Is there a solution that wo ...

The @RequestParam annotation seems to be failing to retrieve a value

When a user inputs their phone number in my application, I want to check if that phone number is already in the database. To do this, I am using an onchange event to instantly send the phone number for validation. However, I am facing an issue where the da ...

Using Javascript to dynamically resize jpeg images to a specific predetermined size

Our approach involves resizing a jpeg image on the client side to a fixed size of 1024 by 768 pixels. The process begins with a user selecting an image for upload, with the condition that if the original image's dimensions exceed 1024 or 768, it shoul ...

Filtering data in Laravel can be efficiently achieved by utilizing Laravel's ORM hasmany feature in conjunction with Vue

Hey there, I'm currently working with Laravel ORM and Vue 2. I've encountered some issues with analyzing Json data. Here's my Laravel ORM code: $banner = Banner::with('banner_img')->get(); return response()->json($banner); ...

Can you stop a JavaScript event using another event?

Can you prevent a JavaScript event in the queue from being executed by another event? Situation: I have two ASP.Net controls, Age - TextBox Save - Button There are two JavaScript validation functions, ValidateAge() - verifies if the age is between ...

Removing the mousedown event from elements within a child component: tips and tricks

Two components are involved: DashboardView and DashboardOrderCard. My goal is to prevent the mousedown event from being emitted when either the date picker is clicked or an option is selected from the DashboardOrderCard. How can I accomplish this? Below is ...

The response from the Ajax request showed that the data was not

I am working on a page where I need to refresh a specific div every minute without refreshing the whole page. The div retrieves data from a PHP file that calculates the highest price in another XML file. I have learned that the most effective way to achiev ...

The constant LOCALE_ID is always set to en-US and remains unchanged

app.module.ts import { registerLocaleData } from '@angular/common'; import localeIndia from '@angular/common/locales/en-IN'; import additionalLocaleIndia from '@angular/common/locales/extra/en-IN'; registerLocaleData(localeInd ...

a common pattern used to substitute website links

I am trying to modify my code that creates HTML links from plain text. While it currently works well, I want to exclude any links that contain .png or .jpg extensions. Does anyone have suggestions on how to adjust the regular expression? var urlPattern ...

Looking to activate a button through JavaScript in HTML5?

Can you help me troubleshoot this JavaScript code for enabling a button when the user enters text? Is it possible that the issue lies with using fieldset? function setText() { var x = document.getElementById("mail").value; if (x != "") { documen ...

Automatically identify the appropriate data type using a type hint mechanism

Can data be interpreted differently based on a 'type-field'? I am currently loading data from the same file with known type definitions. The current approach displays all fields, but I would like to automatically determine which type is applicab ...