Choose a single entity from the ngrx store and display it in a separate template

I have been working on a blog application that utilizes ngrx for state management. Currently, there are two main objects stored in the application:

{
"posts": [...],
"users": [...]
}

Now, I am looking to create a separate component specifically for displaying individual posts (selected-post.component). To achieve this, I attempted to select the post entity based on its ID using the following selector:

export const selectPostById = (id: string) => createSelector(
  selectEntities,
  entities => entities[id]
);

Then, within the component, I retrieved the post using:

postId: string = localStorage.getItem("_selectedPostId");

selectedPost: Observable<Post> = this.store.select(selectPostById(postId));

To display the selected post in the view, I utilized the following code:

<ng-container *ngIf="selectedPost | async">
  <div class="post text-light">
    <div class="p-title fs-3">{{(selectedPost | async).title}}</div>
    <div class="p-image">
      <img [src]="(selectedPost | async).imageSrc">
    </div>
    <div class="p-cont fs-5">
      {{(selectedPost | async).content}}
    </div>
    <div class="p-category float-start fs-6">
      <a class="p-1" href="categories/category" *ngFor="let ct of (selectedPost | async).categories">
        {{ct}}
      </a>
    </div>
    // additional post details...
</ng-container>

However, I encountered an issue where the post was not displayed and received the error message in the console:

ERROR TypeError: Cannot read properties of undefined (reading: '1')

Despite selecting the post with the ID "1" which is present in the state as confirmed by redux devtools.

Looking for any suggestions or insights on resolving this issue.

EDIT: Here is the relevant reducer code:

// Reducer code...

Answer №1

To establish a connection between the `selectEntities` selector from the adapter and the `feature` one (which is generated by the `createFeatureSelector` function), you need to follow these steps:

Try out the code snippet below for implementation:

// Selectors
const { selectIds, selectEntities, selectAll, selectTotal } = adapter.getSelectors();

const feature = createFeatureSelector<PostState>('posts');

// ...

// Combine feature and selectEntities selectors to create a new selector.
export const selectPostEntities = createSelector(feature, selectEntities);

// Utilize the `selectPostEntities` selector to retrieve the specific entity based on its Id.
export const selectPostById = (id: number) =>
    createSelector(selectPostEntities, (entities) => entities[id]);

Moreover, enhance the efficiency of your component template by subscribing to the `selectedPost` observable using the `async` pipe only once, like so:

<ng-container *ngIf="selectedPost | async as _selectedPost">
<!-- Now you can directly access the `_selectedPost` variable without requiring the `async` pipe within the ng-container -->
</ng-container>

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

What is the reason behind the absence of a hide/show column feature in the Kendo Grid for Angular?

In my Angular application, I have implemented a Kendo Grid for Angular with the columnMenu feature enabled. This feature allows users to hide/show columns from a popup: https://i.sstatic.net/B5VXo.png Surprisingly, upon checking the ColumnMenu documentat ...

Error in Typescript: The identifier 'Proxy' is unknown

I'm trying to create a new variable using the Proxy type from the ES6 specification: myProxy: Proxy; However, I'm encountering the following error: Cannot find name 'Proxy'. Can anyone point me in the right direction to resolve th ...

What is the prescribed interface or datatype for symbol type in TypeScript with JavaScript?

I have a set of symbol values in JavaScript that I want to convert to TypeScript. // Defining object values in JavaScript const size = { Large: Symbol('large'), Medium: Symbol('medium') } What is the most efficient method to conv ...

Can one capture audio from the microphone within the world of Decentraland?

Currently facing difficulties capturing voice from microphone in Decentraland, but successfully able to convert mp3 files to text. Seeking assistance from anyone experienced with voice capture in Decentraland. 1. Is it feasible to record voice directly fr ...

Leverage Ramda's clone function within a pipeline in a manner that ensures type safety

My goal is to utilize Ramda for cloning and updating objects in a type-safe manner, drawing inspiration from this approach. However, I am facing challenges implementing it in a type-safe way. Updating a nested object seems to work perfectly fine in a type ...

Using TypeScript: Implementing array mapping with an ES6 Map

If I have an array of key-value objects like this: const data = [ {key: "object1", value: "data1"}, {key: "object2", value: "data2"}, {key: "object3", value: "data3"}, ] const mappedData = data.map(x => [x.key, x.value]); const ES6Map = n ...

Incorporate external JavaScript files into a cutting-edge Ionic 5 / Angular 9 project

I need assistance in incorporating jQuery functions into my Ionic 5/Angular 9 project. In order to access some of the functions, I have included the necessary files in the angular.json file and installed Jquery and Bootstrap through npm. However, I am un ...

The React context hooks are failing to update all references

In my project, I am working on setting up a modal with a custom close callback. To achieve this, I used a useState hook to store the method and execute it within an already defined function called closeModal(). However, I encountered an issue when attempt ...

Managing arrays in local storage with Angular 2+

I seem to be missing a crucial element in my endeavor to save and retrieve an array in local storage within my Angular 4 application. The array is fetched from the server and stored in a variable named 'aToDo' with type 'any', like so: ...

Is it a good idea to integrate TypeScript with JavaScript before uploading to the server?

Our team has been exclusively using nodejs and writing code in vanilla JavaScript with a .js extension. While everything was running smoothly, we've recently made the decision to switch to TypeScript for our nodejs app development. However, we are fac ...

By default, Angular 6 now imports RxJS 6 operators seamlessly into its files

My Angular application extensively uses various RxJS 6 operators like filter, take, and takeUntil in almost all files. Importing these operators explicitly in every file is quite cumbersome. I wish there was a way to make them globally accessible. Imagine ...

The type '{}' cannot be assigned to type 'IntrinsicAttributes & FieldsProp'. This error message is unclear and difficult to understand

"The error message "Type '{}' is not assignable to type 'IntrinsicAttributes & FieldsProp'.ts(2322)" is difficult to understand. When I encountered this typeerror" import { useState } from "react"; import { Card } fr ...

Is the regex returning the correct result?

I need to discuss the date field with a format of YYYYMMDD, as shown below: zod.string().max(8).regex(new RegExp('^(19[0-9][0-9]|20[0-9][0-9]|[0-1][0-9]{3})(1[0-2]|0[1-9])(3[01]|[0-2][1-9]|[12]0)$')); The value provided is 20001915. The definit ...

What is the recommended module to choose when importing MAT_DIALOG_DATA?

When working on my Angular project, I noticed that there are multiple options available for importing MAT_DIALOG_DATA. I have tried importing both @angular/material and @angular/material/dialog, and found that both options work successfully. However, I a ...

Steps for making an Angular 6 POST request using OAuth2 authentication and setting the appropriate headers

I am struggling to correctly format a post request to a Spring Boot OAuth 2 Authorization Server in order to obtain the JWT token. Postman returns the token successfully and the Authorization Server is functioning properly. However, when trying to make the ...

Unable to locate the image file path in React.js

I'm having trouble importing images into my project. Even though I have saved them locally, they cannot be found when I try to import them. import {portfolio} from './portfolio.png' This leads to the error message: "Cannot find module &apos ...

Encountering an error while receiving a response for the Update API request

Recently, I ventured into the world of swagger and decided to test it out with a small demo project in node-js. I successfully created 5 APIs, but encountered an issue specifically with the PUT API. Surprisingly, when testing it on Postman, everything work ...

Troubleshooting an Angular application in Intellij using Chrome on a Windows operating system

I've been searching for a long time for a way to debug an Angular app in IntelliJ using Chrome on Windows. So far, I have not been successful in attaching a debugger to Chrome. I have tried launching Chrome with --remote-debugging-port=9222 and numer ...

Using Angular 4's Renderer2 to handle dynamic element IDs

Could you please advise on how to retrieve a dynamic id from the component (ts) file using the format below? Note: My goal is to scroll the content to the specific dynamic item when a user clicks a button (in this case, it's an item in a Bar chart). ...

While attempting to utilize npm install, I encounter an error on a discord bot stating "msvsVersion is not defined."

Struggling with self-hosting a TypeScript discord bot, the setup process has been a puzzle. It's supposed to generate a build directory with an index.js file, but it's unclear. Installed Visual Studio Build Tools 2017 as required, yet running npm ...