Leveraging NgRx for Managing Arrays

export class Ingredient {
    public name: string;
    public amount: number;

    constructor(name: string, amount: number) {
        this.name = name;
        this.amount = amount;
    }
}

List of Ingredients:

export const initialIngredients: Ingredient[] = [
  new Ingredient('Apples', 5),
  new Ingredient('Lemons', 10),
  new Ingredient('Cherries', 15),
  new Ingredient('Tangerines', 20),
  new Ingredient('Apricots', 25)
];

Action in NgRx:

export const ADD_INGREDIENT_ACTION = createAction(
    'ADD_INGREDIENT_ACTION',
    props<{ ingredient: Ingredient }>()
);

Reducer Implementation:

export const ingredientsReducer = createReducer(
  initialIngredients,
  on(
    ShoppingListActions.ADD_INGREDIENT2,
    (state, ingredient) => ({ ...state, ingredients: [...state, ingredient] })
  )
);

I'm currently enrolled in an Angular course and experimenting with the latest version for efficiency. I encountered a hurdle while trying to use NgRx for managing state as per my array contents.
My goal is to display the existing elements in the array and seamlessly add new ones but it seems like there's a glitch in my implementation regarding types.
The code snippet below illustrates how the task was accomplished in the previous course using switch/case logic which worked flawlessly.

Code from Previous Course: executed without any issues

export const initialState = {
  ingredients: [
    new Ingredient('Apples', 5),
    new Ingredient('Lemons', 10),
    new Ingredient('Cherries', 15),
    new Ingredient('Tangerines', 20),
    new Ingredient('Apricots', 25)
  ]
};
________________________________________________________
export const ADD_INGREDIENT = 'ADD_INGREDIENT';

export class AddIngredient implements Action {
    readonly type = ADD_INGREDIENT;
    payload: Ingredient;
}
export function shoppingListReducer(state = initialState, action: ShoppingListActions.AddIngredient) {

  switch (action.type) {
    case ShoppingListActions.ADD_INGREDIENT:
      return { ...state, ingredients: [...state.ingredients, action.payload] };
    default:
      return state;
  }
}

Answer №1

When working with your NgRx Reducer, it is recommended to utilize destructuring assignment to unpack the ingredient property and add it to the ingredients array like this:

ingredients: [...state.ingredients, ingredient]

This is an example of how to implement this in your reducer code:

export const shoppingListReducer = createReducer(
  initialState2,
  on(ShoppingListActions.ADD_INGREDIENT2,
    (state, { ingredient }) => ({
      ...state,
      ingredients: [...state.ingredients, ingredient],
    })
  )
);

Answer №2

The issue arises from the use of distinct data types.

While your state is represented as an array within square brackets [];
The state of the course is depicted as an object enclosed in curly braces {};

The mismatch between objects and arrays {…} and […] respectively, is what's leading to the underlying problem.

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

Minimize the cyclomatic complexity of a TypeScript function

I have a typescript function that needs to be refactored to reduce the cyclometric complexity. I am considering implementing an inverted if statement as a solution, but it doesn't seem to make much of a difference. updateSort(s: Sort) { if (s.ac ...

It is impossible for me to invoke a method within a function

I am new to working with typescript and I have encountered an issue while trying to call the drawMarker() method from locateMe(). The problem seems to be arising because I am calling drawMarker from inside the .on('locationfound', function(e: any ...

Difficulty arises when attempting to load Silverlight within an Angular2 component

Issue with Silverlight Component Loading When embedding and loading the Silverlight.xap file directly inside an HTML page, everything works perfectly. However, when we move the same code inside a component, the Silverlight content fails to load. Interest ...

A Guide to Performing Dual API Calls within Angular for a Single Component

Is there a way to make two separate API calls within the same Angular component? For instance, I have an order component that is rendered twice in a tabular manager on a page. Using ngif condition, I display different data for TAB1 and TAB2. The issue is ...

Leveraging functions with Ng-Repeat

I am currently dealing with two different arrays of objects. The first array contains a list of permissions groups, while the second array consists of user groups. My main goal is to compare the Group Owner (which is represented by ID 70) with the list of ...

How do I rearrange the order of a collection in Firestore using a reference that I already have?

Is there a method to maintain a reference of the same collection while altering the ordering using firestore? TLDR: I am looking to achieve similar functionality as demonstrated in: , but since my data is sourced from firestore, I am struggling to find th ...

Issues with type errors in authentication wrapper for getServerSideProps

While working on implementing an auth wrapper for getServerSideProps in Next.js, I encountered some type errors within the hook and on the pages that require it. Below is the code for the wrapper along with the TypeScript error messages. It's importan ...

Loader for dynamically loading tabs in Angular 2

I am looking to develop a dynamic tabs loader using Angular 2 material with specific syntax support. <generic-tabs [tabs]="tabs" tabVisibleField="name"> <test-cmp [tabContent] testData="hello"></test-cmp> ...

Changing the type of an object's property in TypeScript on the fly

I am working on a TypeScript function that is designed to dynamically modify the property of an object. Here is the function: const updateProperty = (value: any, key: keyof Type1, obj: Type1) => { obj[key] = value; } Below is the definition of "Typ ...

Lack of intellisense support for .ts files in Visual Studio Code

Currently, I am using Visual Studio Code 1.17.2 on Arch Linux to kickstart my work with Node.js/Angular4. To avoid confusion caused by loosely typed code, I have decided to switch to TypeScript for my NodeJS server as well. This is why my main file is name ...

Adding a fresh element to an array in Angular 4 using an observable

I am currently working on a page that showcases a list of locations, with the ability to click on each location and display the corresponding assets. Here is how I have structured the template: <li *ngFor="let location of locations" (click)="se ...

Angular component failing to refresh data upon service response

Within my Angular component, I have integrated badges onto certain icons. These badge numbers are fetched from an api upon entering the page, utilizing ionViewWillEnter(). Once the api response is received, the outcome is stored in a local variable, which ...

Discovering the ReturnType in Typescript when applied to functions within functions

Exploring the use of ReturnType to create a type based on return types of object's functions. Take a look at this example object: const sampleObject = { firstFunction: (): number => 1, secondFunction: (): string => 'a', }; The e ...

Reduce the identification number within a JSON array following the removal of an item

Within my local storage, I maintain a dynamic array. Each entry is accompanied by an ID that increments sequentially. If a user opts to delete an entry, it should be removed from the array while ensuring that the IDs remain in ascending order. For example: ...

"What are the necessary components to include in UserDTO and what is the reasoning behind their

Presenting the User entity: package com.yogesh.juvenilebackend.Model; import jakarta.annotation.Generated; import jakarta.persistence.*; import lombok.*; @Entity @Getter @Setter @NoArgsConstructor @AllArgsConstructor @RequiredArgsConstructor public class ...

The name 'withStyles' is nowhere to be found

import * as React from "react"; import Button from "@material-ui/core/Button"; import * as PropTypes from "prop-types"; import {WithStyles} from '@material-ui/core'; import "./App.css"; import PageTwo from "./components/PageTwo"; ...

Display a dynamic array within an Angular2 view

I have a dynamic array that I need to display in the view of a component whenever items are added or removed from it. The array is displayed using the ngOnInit() method in my App Component (ts): import { Component, OnInit } from '@angular/core' ...

Validating Forms in TypeScript

Currently in the process of learning Angular 10, but encountering a challenge I have an HTML document that validates a form group in my component. When I set a value for a textbox from my component, the value is displayed correctly, but my submit button c ...

What is the best way to breakdown the MVC pattern within Angular 2?

Discovered a useful blog about Angular: MVC Implementation, but interested in finding a clear explanation for Angular 2. ...

The attribute 'value' is not present in the object of type 'Readonly<{}>'

My current project involves creating a form that will dynamically display content based on the response from an API. The code I am working with is structured as follows: class Application extends React.Component { constructor(props) { super(props); ...