Mapping Selector Types in Ngrx

Here is the structure of my IStore:

export interface IStore {
  plans: IPlanRedux;
}

The definition of IPlanRedux is as follows:

export interface IPlanRedux {
    entities: { [key: string]: IPlan };
    ids: Array<string>;
}

export interface IPlan {
    id?: string;
    name?: string;
}

To create selectors for the plan state, I have implemented the following selectors:

plan.selectors.ts:

export const getEntities = (planRdx: IPlanRedux) => planRdx.entities;
export const getIds = (planRdx: IPlanRedux) => planRdx.ids;

export const getAll = createSelector(getEntities, getIds, (entities, ids) => { return ids.map(id => entities[id]); });

In addition, in root.selectors.ts:

export const getPlansState = (state: IStore) => state.plans;
export const getPlanEntities = createSelector(getPlansState, fromPlans.getAll);

I encountered a compiler error while trying to subscribe using the getPlanEntities selector in my component to retrieve all entities:

this.store$.select(fromRoot.getPlanEntities)
    .map(plan => {
        if (plan.id != null)
        {
            return {id: plan.id, text: plan.name};
        }
    });

The issue lies with the type of the parameter plan. The compiler indicates that the type of plan is IPlan[], instead of a single IPlan. This results in errors like

Property 'id' does not exist on type 'IPlan[]'
since plan is an array rather than a single object.

I am unsure how to resolve this problem. Is there a way to access individual entities one by one instead of receiving them as an array?

EDIT

The objective is to obtain an Observable<IPlan> in my component from

this.store$.select(fromRoot.getPlanEntities)
:

private plans$: Observable<IPlan>;
constructor(private store$: Store<IStore>, private fb: FormBuilder, private router: Router, injector: Injector)
{
    this.plans$ = this.store$.select(fromRoot.getPlanEntities)
        .map(planEntities => {
            return planEntities
                .find(plan => plan.id != null)
                .map(plan => ({id :plan.id, text: plan.name}));
        });
 ...

This can then be utilized in the template to display all current plans:

<div class="clearfix">
    <div *ngIf="plans$ | async">
        <div [innerHTML]="(plans$ | async).name"></div>
   </div>

Answer №1

Perhaps there was some confusion regarding the usage of map in this code snippet:

this.store$.select(fromRoot.getPlanEntities)
  .map(plan => {
      if (plan.id != null)
      {
          return {id: plan.id, text: plan.name};
      }
  });

Just to clarify, this is not an ES6 map, but rather a map function applied to an Observable. Essentially, you are fetching your planEntities. If you intend to retrieve a single entity, you can modify the code like so:

this.store$.select(fromRoot.getPlanEntities)
  .map(planEntities => {
    return planEntities
      .find(plan => plan.id !== null)
      .map(plan => ({ id: plan.id, text: plan.name }));
  })
  .do((plan: {id: any, text: string}) => /* PERFORM ACTIONS HERE */);

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

I need to dynamically change the font color based on the data retrieved from the API

I am looking to dynamically change my font color. <div *ngIf="clientProfileModel.patientHealthScore[0].kidneyScoreStatusByColor==='Normal'" [ngStyle]="{color:'#ff5454'}" then *ngIf="clientProfileModel.pat ...

Utilize Type Script/Angular 8 for seamless file management by either dragging and dropping files or selecting

Can you provide guidance on using the ng-upload-file plugin with TypeScript? https://github.com/danialfarid/ng-file-upload I attempted to implement it but encountered difficulties. Do you have a working sample available or know of another open-source plu ...

Issue with Angular2: Trouble transmitting data to another component. The backend service is being invoked twice

My current project requires me to extract query parameters from a URL in the ngOnInit function, create a specific URL for calling an API on the backend like http://localhost:8080/myapp/video0=5&video1=6, and then send the received data to another compo ...

Tips for passing certain optional parameters while excluding others without resorting to undefined or empty values like ""

Is there a way to invoke the function while omitting certain optional parameters without resorting to undefined and empty strings? import { MouseEvent } from "react"; import { DialogType } from "editor-constants"; export interface Dial ...

Using Angular to subscribe to a BehabiourSubject within a service

Within the service itself, I am attempting to subscribe to the BehaviorSubject currentTheme. @Injectable({providedIn: 'root'}) export class ThemeService { currentTheme: BehaviorSubject<string>; constructor(@Inject(DOCUMENT) private docu ...

The Bootstrap modal backdrop is now displaying prominently in front of the modal following the latest Chrome update

Chrome version: Version 111.0.5563.64 (Official Build) (x86_64) Bootstrap: 4.3.1 Recently, there has been an issue with the modal backdrop appearing in front of the modal itself after a Chrome update. The problem does not seem to be related to z-index, an ...

Prioritize the timepicker over the use of a modal window

Having an issue with my time picker in Angular being blocked by a modal window. Component.ts open() { const amazingTimePicker = this.atp.open(); amazingTimePicker.afterClose().subscribe(time => { console.log(time); }); } // T ...

Navigating Date Conversion within Component in Angular 2 Application

Searching for a way to update the display of certain dates in my Angular 2 application, I encountered a roadblock. Using the date pipe in conjunction with string interpolation wasn't viable due to the structure of my template code: <input class="a ...

I am currently leveraging Angular 17, but I have yet to enable Vite. Can anyone guide me on

Despite having the most recent version of NX and Angular, my app has not yet integrated Vite. I've come across online suggestions on how to enable it, but none of them make sense to me because my project doesn't have an angular.json file. Instead ...

Restrict a class to contain only functions that have a defined signature

Within my application, I have various classes dedicated to generating XML strings. Each of these classes contains specific methods that take input arguments and produce a string output. In order to enforce this structure and prevent the addition of methods ...

Elevate your Material UI Avatar with an added level of

Attempting to give a MUI Avatar component some elevation or shadow according to the documentation provided here. <Avatar alt="Cindy Baker" src="/static/images/avatar/3.jpg" /> Enclosing the Avatar within a paper or Card element increases the size o ...

Verify whether a web application is equipped with React, Angular, or Vue

Is there an easy way to identify the client-side libraries used by an application if they are minified or compressed? While examining all the JavaScript sent from the server to the client, it can be challenging to determine if one of the top three popular ...

Mapping Observable.forkJoin() responses to the respective requests can be achieved by following these steps

I have a tool that uses the httpClient to generate response observables for a pipe. I also have a collection of request URLs. This is how the code appears: let observables = urls.map(url=>myPipe.transform(url)); forkJoin(observables).subscribe(results=& ...

Angular Fusion: Delay execution of ngAfterViewInit until data is received from API call in ngOnInit

I'm facing an issue with my code where the API call in ngOnInit is not waiting for the data to be returned before moving on to ngAfterViewInit. I need it to wait because I am performing operations on that data in ngAfterViewInit, but currently, it&apo ...

Data that changes dynamically on a chart

When making a rest call to fetch data, I aim to populate the pieChartData with the obtained information. However, I am facing difficulties in achieving this task. Can someone guide me on how to accomplish this? import { Component, OnInit} from '@angu ...

Tips on excluding node_modules from typescript in Next.js 13

I am constructing a website in the next 13 versions with TypeScript, using the src folder and app directory. When I execute `npm run dev`, everything functions correctly. However, upon building, I encounter this error... ./node_modules/next-auth/src/core/l ...

Definition of composed types in TypeScript generics

I'm curious if there is a functional distinction between the two TypeScript type declarations below: object: Observable<number> | Observable<number[]> object: Observable<number | number[]> If there is a difference, what are the ...

Utilize an exported es6 module of a web component within an Angular project

I have developed a library consisting of web components which are exported using rollup. The bundle includes exports like: export { Input, Button }; where Input and Button are ES6 classes defined within the bundle itself. After publishing this library ...

Two trigger functions in Angular animations are not functioning as expected

After updating to the latest version of Angular and starting a new project, I encountered an issue with using two trigger() functions for animations. When attempting to use both trigger() functions, the second one would not work. However, disabling the fir ...

Angular 6: Unable to resolve parameters for Component: (?)

We have been using Angular v6.0.0-beta.3 for a while now, but we recently attempted to upgrade to version 6.1.3. Unfortunately, I faced issues upgrading with Angular schematics due to lack of support for external registries like Artifactory. As a result, ...