Issue with selecting an individual value in NGRX entity using id

My goal is to retrieve an object by its Id from the entity state using a reducer. Here is the implementation:

 export interface MessageState extends EntityState<Message> {
  // additional entities state properties
  loaded: boolean;
  loading: boolean;
}

export const adapter: EntityAdapter<Message> = createEntityAdapter<Message>({
  selectId: (msg: Message) => msg.messageId,
});

export const initialState: MessageState = adapter.getInitialState({
  // additional entity state properties
  loaded: false,
  loading: false,
});

export function reducer(state = initialState, action: MessageActionsUnion): MessageState {
  switch (action.type) {

    case MessageActionTypes.UPSERT_Message: {
      return { ...state, loading: true, loaded: false };
    }

    case MessageActionTypes.UPSERT_Message_SUCCESS: {
      return adapter.upsertOne(action.payload.Message,
        {
          ...state, loaded: true, loading: false,
        });

    }

    default: {
      return state;
    }
  }
}

Here is the content of my index.ts file:

export interface State extends fromRoot.AppState {
  queueModule: QueueState;
}

export interface QueueState {
  msgHeaders: fromMsgHeaders.MessageHeaderState
}

export const reducers: ActionReducerMap<QueueState> = {
  msgHeaders: fromMsgHeaders.reducer

};

export const getQueueState$ = createFeatureSelector<QueueState>('queueModule');

I am working on creating a selector that can fetch an object by passing its Id:

    export const selectMessages = createSelector(
      fromFeatures.getQueueState$,
      (state: fromFeatures.QueueState) => state.msgs
    );

    export const {
      selectAll: selectAllMessages,
      selectEntities: selectMessagesEntities,
      selectIds: selectMessagesIds,
      selectTotal: selectMessagesTotal
    } = adapter.getSelectors(selectMessages);

I have gone through multiple resources, but I haven't found a clear explanation on how to achieve object selection based on Id.

Answer №1

@ngrx/entity introduced the dictionary feature in their v6.1.0 release (check out ngrx entity changelog here) which included a new method called getEntityValueById.

This allowed me to easily fetch a single value of an entity using its id as shown below.

// Using the selector
import { Dictionary} from '@ngrx/entity;

export const getMessageById = () => {
  return createSelector(
    selectMessagesEntities,                
    (entities: Dictionary<Message>, props: { messageId: number }) => {
      return entities[props.messageId];
    },
  );
};


// Calling the selector


this.msg$ = this.store.pipe(select(
      fromStore.getMessageById(), { messageId: 10 }
    )).pipe(
      map(
        (message: Message) => {
          return this.msg = message;
        },
      )
    );

If you want more information on this topic, there is a detailed article available here.

Answer №2

@ngrx/entity does not come with a built-in getOneById selector.

In most scenarios, you shouldn't need to manually create this type of selector.

However, if necessary, it is possible to craft a custom selector for this purpose. For detailed guidance on how to achieve this, refer to the article titled "NgRx: Parameterized selectors" at [.

Here is an example:

export const getCount = createSelector(
  getCounterValue, 
  (counter, props) => counter * props.multiply
);

export const selectCustomer = (id: string) => createSelector(
  selectCustomers,
  customers => customers[id]
);

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

Form control named 'startTime' and 'endTime' do not have a valid value accessor

The app.module file contains the following code: import { TimepickerModule, TimepickerConfig } from 'ngx-bootstrap/timepicker'; import { getTimepickerConfig } from './TimepickerConfig'; imports: [ BsDatepickerModule.forRoot(), Tim ...

How can I access properties of generic types in TypeScript?

Converting the generic type to any is a valid approach (The type E could be a typescript type, class, or interface) of various entities like Product, Post, Todo, Customer, etc.: function test<E>(o:E):string { return (o as any)['property' ...

Utilizing props in styled-components: A beginner's guide

I am trying to pass a URL to a component so that I can use it as the background image of the component. Additionally, I need to check if the URL is empty. Component: <BannerImg/> CSS (styled): `const BannerImg = styled.img` background-image: url( ...

How to Retrieve a Symbol in TypeScript

In the code snippet below, there is a function named factory that returns a Symbol of type Bob. However, TypeScript appears to forget the type of the return value immediately, leading to an error when trying to assign the return value to variable test one ...

Managing Visual Studio Code Extension Intellisense: A Guide

I am looking to create an extension I recommend using "CompletionList" for users. Users can trigger completion by running "editor.action.triggerSuggest" The process of my extensions is as follows: Users input text If they press the "completion command," ...

Using the BrowserAnimationModule with the HTMLCanvasElement

I am facing an issue while integrating Angular Material Dialog with my component that includes an HTMLCanvas element for drawing. It seems like the BrowserAnimationModule, which is imported in app.module.ts and used by Material Dialog, is causing a delay i ...

Angular Universal: Dividing projects [A resolution for dated or intricate projects]

Working on an aging Angular project that has been through multiple upgrades since the 2.0 release, we are currently at version 4.3. The project has become quite complex over time, with numerous features and outdated peer dependencies that are no longer be ...

The ngModel of ControlValueAccessor does not reflect changes in value when the event is triggered

I am working on a component that utilizes controlvalueaccessor to bind ngModel passed from the parent component password.component.ts: import { Component, ElementRef, forwardRef, HostListener, Input, OnChanges, OnInit, SimpleChanges } ...

Setting up Bootstrap 5 with the latest version of Angular, which is Angular

I attempted to install Bootstrap in Angular 13 using the following link: However, after updating to bootstrap v5, the styles are not displaying correctly. Interestingly, it works fine with bootstrap 4.6.1. I followed all the steps in the provided link. I ...

Download pictures from swift into typescript with the help of share extensions

Currently, I am working on setting up Share Extensions in my ionic3 application. To begin with, I followed these steps: Firstly, I built the app and then launched it in Xcode. After that, I added a Share Extension by navigating to File -> New -> Ta ...

How to Pass Values in handleChange Event in Typescript

I have noticed that most online examples of handling change events only pass in the event parameter, making the value accessible automatically. However, I encountered an error stating that the value is not found when trying to use it in my handleChange fun ...

Angular error TS2339: The property 'before' is not found on type 'HTMLElement' / 'HTMLTextAreaElement' / etc

Objective: My goal is to reposition a div (containing a mat-select dropdown) ABOVE a mat-card-title when the user is accessing the site from a mobile device. If the user is not on a mobile device, the div should remain in its original position to the right ...

Stop any ongoing search requests in Angular 7 using Ng2SmartTable

My current setup involves Angular version 7.0.1 and ng2-smart-table version 1.4.0. The issue I'm facing is that each search within the table triggers a new API request to fetch data. What I actually want is for only the latest search request to be pro ...

When using `router.navigateByUrl` in Angular, make sure to exclude any additional values

I'm attempting to pass a single value between Angular components... but when I reach my component, I'm not receiving anything. Component1: onCellClicked(event) { if (event.colDef.field === 'dni') { console.log('dni in m ...

Incorporate HTML elements within an Angular component

Looking to dynamically add an Angular HTML element to a component at runtime. Imagine the HTML element is an H1 tag with an Angular expression: <h1>{{testHeading}}</h1> The goal is to insert this tag into a component while preserving its dy ...

Implementing dynamic styles for a checked mat-button-toggle in Angular 6

How can I customize my button-toggle when it is checked? The current code I have doesn't seem to be working... This is the code snippet: <mat-button-toggle-group #mytoggle (change)="selectoption($event)" value="{{num}}"> <mat-bu ...

Typescript causing undefined React Router match issue

Currently, I am working on a basic eCommerce Proof of Concept using react and TypeScript. Unfortunately, I am facing an issue where I am unable to pass props to a product detail page or access the match containing the params. This is how my Routes pages a ...

Can anyone provide guidance on creating a new type in Ionic Vue?

How can I define the description as a type in my code? When I run it, I get an error that says "Property 'description' does not exist on type '{ takePhoto(): Promise; }'" <script lang="ts"> import { IonPage, ...

Creating a default option in a Select tag with React when iterating over elements using the map method

After learning that each element in the dropdown must be given by the Option tag when using Select, I created an array of values for the dropdown: a = ['hai','hello','what'] To optimize my code, I wrote it in the following ...

Tips for accessing data from a local JSON file in your React JS + Typescript application

I'm currently attempting to read a local JSON file within a ReactJS + Typescript office add-in app. To achieve this, I created a typings.d.ts file in the src directory with the following content. declare module "*.json" { const value: any; ex ...