Issue with Angular ngrx add/del operation causing unexpected undefined return value

Within my application, I am retrieving a list of Vehicle IDs from my web API.

The problem arises when I attempt to add an ID to the list using the "add" button, as it simply adds an "undefined" value instead. However, when I directly subscribe to the service without involving ngrx store, the process works smoothly for both adding and deleting IDs.

Below are the snippets related to effects and reducers from ngrx store, along with my service and functions for adding and deleting:

//ngrx/store/effect
  @Injectable()
export class FavVehiclesIdEffects {
  constructor(
    private actions$: Actions,
    private vehicleService: VehicleService
  ) {}

  // Effects for loading favorite vehicles IDs
  @Effect()
  loadFavVehiclesId$ = this.actions$
    .ofType(favVehiclesIdAction.LOAD_FAVVEHICLES_ID)
    .pipe(
      switchMap(() => {
        return this.vehicleService.getFavourite().pipe(
          map(
            favVehiclesId =>
              new favVehiclesIdAction.LoadFavVehiclesIdSuccess(favVehiclesId)
          ),
          catchError(error =>
            of(new favVehiclesIdAction.LoadFavVehiclesIdFail(error))
          )
        );
      })
    );

  // Effects for adding favorite vehicles IDs
  @Effect()
  addFavVehiclesId$ = this.actions$
    .ofType(favVehiclesIdAction.ADD_FAVVEHICLES_ID)
    .pipe(
      map((action: favVehiclesIdAction.AddFavVehiclesId) => action.payload),
      switchMap(favvehiclesid => {
        return this.vehicleService.addVehicle(favvehiclesid).pipe(
          map(
            favvehicleid =>
              new favVehiclesIdAction.AddFavVehiclesIdSuccess(favvehicleid)
          ),
          catchError(error =>
            of(new favVehiclesIdAction.AddFavVehiclesIdFail(error))
          )
        );
      })
    );

  // Effects for deleting favorite vehicles IDs
  @Effect()
  deleteFavVehiclesId$ = this.actions$
    .ofType(favVehiclesIdAction.DELETE_FAVVEHICLES_ID)
    .pipe(
      map((action: favVehiclesIdAction.DeleteFavVehiclesId) => action.payload),
      switchMap(favvehiclesid => {
        return this.vehicleService.deleteVehicle(favvehiclesid).pipe(
          map(
            () =>
              new favVehiclesIdAction.DeleteFavVehiclesIdSuccess(favvehiclesid)
          ),
          catchError(error =>
            of(new favVehiclesIdAction.DeleteFavVehiclesIdFail(error))
          )
        );
      })
    );
}

//ngrx/store/reducer
export interface FavVehiclesIdState {
  entities: { [id: number]: Tracker };
  loaded: boolean;
  loading: boolean;
}

export const initialState: FavVehiclesIdState = {
  entities: {},
  loaded: false,
  loading: false
};

export function reducer(
  state = initialState,
  action: fromFavVehiclesId.FavVehiclesIdAction
): FavVehiclesIdState {
  switch (action.type) {
    case fromFavVehiclesId.LOAD_FAVVEHICLES_ID: {
      return {
        ...state,
        loading: true
      };
    }
    ...
  }
  return state;
}

export const getFavVehiclesIdEntities = (state: FavVehiclesIdState) =>
  state.entities;
...


//services.ts
getFavourite(): Observable<Tracker[]> {
    const url = `${this.API_URL}/favourites`;
    return this.http.get<Tracker[]>(url).pipe(
      tap(() => this.log(`fetched favVehicles id`)),
      catchError(this.handleError('getVehicles', []))
    );
  }

// Service for "add to favourite" button
  addVehicle(track: Tracker): Observable<Tracker> {
    const url = `${this.API_URL}/favourites`;
    const service = this.http.post<Tracker>(url, track, this.httpOptions).pipe(
      tap(_ => this.log(`adding vehicle id=${track.id}`)),
      catchError(this.handleError<Tracker>('addVehicle'))
    );
    console.log(service);
    return service;
  }

  // Service for "delete from favourite" button
  deleteVehicle(track: Tracker): Observable<Tracker> {
    const url = `${this.API_URL}/favourites`;
    const service = this.http.put<Tracker>(url, track, this.httpOptions).pipe(
      tap(_ => this.log(`deleted vehicle id=${track.id}`)),
      catchError(this.handleError<Tracker>('deleteVehicle'))
    );
    console.log(service);
    return service;
  }

 // component.ts
 addFav(event: VehicleDetail) {

      const temp = new Tracker();
      temp.id = event.id;

      // updating JSON file
      this.store.dispatch(new fromStore.AddFavVehiclesId(temp));

      this.store.dispatch(new fromStore.LoadFavVehiclesId());

    }
  }
  // Function for deleting selected vehicle from favorites
  deleteFav(event: VehicleDetail, text: string) {
      const temp = new Tracker();
      temp.id = event.id;

      // removing from JSON file
      this.store.dispatch(new fromStore.DeleteFavVehiclesId(temp));

      this.store.dispatch(new fromStore.LoadFavVehiclesId());

    }
  }

Although my GET method is functioning properly, I suspect that there might be issues in my mapping process, where I extract the ID from "VehicleDetail" and assign it to my custom type "Tracker". I have experimented with different approaches but remain perplexed, given that I followed a tutorial closely. The JSON file updates correctly, suggesting that the problem lies within my ngrx store implementation. Can anyone spot what's going wrong here? Please ask if you need any further clarification or details.

Update

https://i.sstatic.net/OQjgA.png

My entries seem to be undefined. Is there anything amiss in my reducer file?

To provide better context, below is my definition of the "Tracker" class:

export class Tracker {
  id: number;
}

Answer №1

My suggestion for improving the reducer logic when adding a vehicle is as follows:

case fromFavVehiclesId.ADD_FAVVEHICLES_ID_SUCCESS: {
  const favvehiclesid = action.payload;
  const entities = [...state.entities, favvehiclesid];
  return {
    ...state,
    entities
  };
}

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

Service for language translation in Angular

I attempted to use an angular translation service to translate English words to Chinese using a key-value mapping approach, but unfortunately, I was unsuccessful. Does anyone have any suggestions? Here is the JSON mapping: "At most {{ number }} wrods ...

A guide on exporting table data to PDF and enabling printing features in Angular 7

Can anyone provide guidance on how to export my dynamic table data into Excel, PDF, and for printing using the appropriate Angular Material components and npm plugins? I have successfully exported the data as an Excel file, but am struggling with exporti ...

Filter that caters to specific number of properties of X

Looking to create a versatile filter function that can handle multiple criteria? Here's a snippet of the current filtering function: const filterRows = () => { items.filter((item) => { if(selectedDrinks.length > 0 && select ...

Guide to invoking the API prior to shutting down the browser window in Angular4

Currently, I am working on an Angular 4 application that consists of 5 components. My goal is to trigger an API call when the user closes the browser window from any one of these components. However, I have encountered an issue where the API does not get ...

Angular 5 - capturing form inputs - activating event upon selecting suggested values

When I click on suggested values below the input field, the (click)="doSomething()" event doesn't fire. How do I handle this issue? I would like to be able to type something in the input field and then have an event triggered when clicking on the su ...

Retrieve highlighted text along with its corresponding tag in ReactJS

my <span class="highlight">highlighted</span> word The text above is showing an example including HTML tags. However, when using window.getSelection(), only the text "my highlighted word" is returned without the surrounding <span& ...

Tips for efficiently combining mergeMap observables and providing a singular value for the entire observable

Consider this particular case involving TypeScript/angular with rxjs 6.5: main(){ const items = ['session', 'user']; const source: Observable<any> = from(items); source .pipe( ...

Ways to transfer an array between two unrelated components using a shared service and BehaviorSubject in Angular

I have been facing difficulties passing an array from one component to another. The issue arises when the array is passed between components and ends up being empty. Despite seeing integers in the console, the array is being passed before any values are pu ...

How do I go about adding <li> elements from component A to a favorites list in component B using Angular?

I'm currently working on a movie database project, and I'm trying to implement a feature where users can add movies from the "search-movie" component to a "favourites" component by clicking an "add to fav" button. I've been attempting to use ...

Conditional types fail to narrow down accurately

My function has the capability to do either of the following: Process a string search term and return a Promise Process a string search term along with a callback function, returning nothing (void) Here is how the implementation looks like: function fetc ...

Utilize ngrx effects for making API requests without storing the response in the store

Currently, I am working on an Angular project that utilizes ngrx/store. One of my components requires data from the backend. The usual flow for this scenario is as follows: dispatch a Action trigger an Effect --> make a call to the backend update the ...

Loading custom components dynamically in Angular with SVG: a how-to guide

Looking for a way to dynamically load SVG items with ease. The items needed are quite simple. Here's a basic template: <svg:rect [attr.x]="x" [attr.y]="y" width="10" height="10" /> Component Class Example: export class DraggableSvgItemCompon ...

What is the best way to link a specific version of the @types package to its corresponding JavaScript package version?

Currently, I am in the process of working on a nodejs project with typescript 2.2 that relies on node version 6.3.1. My goal is to transition from using typings to utilizing @types. However, during this migration, several questions have arisen regarding th ...

Utilizing Typescript's baseUrl compiler configuration for node development

Is there a way for node's module loader to support TS's baseUrl compiler option? With the introduction of the baseUrl compiler option in TS 2, project relative require() and import requests are now possible. However, this feature requires that ...

Obtaining the statusCode in AngularWould you like to learn

Is there a way to create a method that can retrieve the status code of a request? I am currently working with Angular 15. This is my get method in the service: public getData( ano: any, mes: any, glosadas: any, pagina:any): Observable<any> { const ...

Having trouble retrieving data from redux toolkit using typescript

I've been diving into the world of Typescript by building a simple todo app using React, Redux-toolkit, and Typescript. One issue I encountered is when trying to access data from the store with useSelector. The retrieved object contains the desired va ...

Incorporating Fonts package and CSS frameworks into Angular Story Book - A guide

How can external fonts be included in Angular storybook, especially when using materialize css and google fonts? <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?f ...

How can I prevent right-clicking with Ctrl+LeftMouseClick in Firefox on MacOS?

I'm looking to implement a shortcut using Ctrl+LeftMouseClick in my React project. It functions perfectly on Chrome on my Mac, but in Firefox the shortcut initiates a right mouse click (event.button = 2). I believe this may be due to MacOS's Rig ...

Revamp the button's visual presentation when it is in an active state

Currently, I'm facing a challenge with altering the visual appearance of a button. Specifically, I want to make it resemble an arrow protruding from it, indicating that it is the active button. The button in question is enclosed within a card componen ...

Combining data from select dropdown menus in Angular forms

Is it possible to combine values from dropdown menus into an array of objects? Two dropdown menus are available, one for selecting persons and the other for selecting countries, both pre-populated with values. https://i.sstatic.net/pfe5n.png The objectiv ...