Utilize ngrx and rxjs to transform an Observable from createSelector (TS2740: Type 'MemoizedSelector error)

My usual method of fetching data from the ngrx store used to be:

public getUser(): Observable<IUser> {
  return this.store.select(store => store.users.selectedUser);
}

However, I am now attempting to transition to using createSelecor (ngrx 15) and have tried the following:

 public getUser(): Observable<IUser> {
        const user = createSelector((state: IAppState) => state.users,
            (userState) => {
                return userState;
            }
        );
        return user;
    }

This new approach is resulting in an error:

TS2740: Type 'MemoizedSelector<IAppState, IUserState, (s1: IUserState) => IUserState>' is missing the following properties from type 'Observable<IUser>': source, operator, lift, subscribe, and 3 more.

So my question is, how can I obtain an Observable from createSelecor in order to perform the following:

        this.storeSelector.getUser().subscribe((a) => {
            console.log(a);
        });

TypeScript is indicating a problem with the return type as Observable<IUser>.

Thank you.

Answer №1

Your response makes a valid point about the lack of memoization in the example provided. It seems that declaring a new selector each time may be causing this issue.

Considering the simplicity of the getUserMemoize function, it might be more efficient to utilize its body directly instead of calling it separately.

export const getUser = createSelector((state: IAppState) => state.users,
  (userState) => userState.selectedUser
 ));

...
public getUserMemoize(){
  return this.store.select(getUsers);
}

// Or use directly
const users$ = this.store.select(getUsers);

You also mentioned a combination approach in your subsequent explanation:


const getUsers = createSelector((state: IAppState) => state.users, (userState) => userState);
const getConfig = createSelector((state: IAppState) => state.config, (userState) => userState);

const getCombined = createSelector(
  getUsers,
  getConfig,
  (users, config) => ({ users, config}));

const combined$ = this.store.select(getCombined);

It's crucial to avoid recalling createSelector as doing so will create a new instance without retaining the previous state for proper memoization.

Instead of wrapping it in a separate function, it is advisable to directly utilize combined$.

Answer №2

Is this the correct approach?

    ...
    private selectorCombined$;
    ...
getUserCombinesExample5(): Observable<{ u: IUser, c: IUIConfigState }> {
        if (!this.selectorCombined$) {
            alert('create instance once selectorCombined$');
            const users = createSelector((state: IAppState) => state.users, (userState) => userState);
            const config = createSelector((state: IAppState) => state.config, (userState) => userState);
            this.selectorCombined$ = createSelector(users, config,
                (i_users1, i_config) => {
                    return {u: i_users1, c: i_config};
                },
            );
        }
        return this.store.select(this.selectorCombined$)
            .pipe(map((v: { u: IUser, c: IUIConfigState }) => {
                    return v;
                })
            );
    }

Any feedback on this code snippet?

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

Encountered an issue with ionViewDidLoad: The property 'firstChild' cannot be read as it is null

While working on an Ionic 2 App with Angular2 and Typescript, I encountered an issue when trying to pass a JSON to map for markers. Here is the link to the gist containing the code snippet I am facing an error that reads: view-controller.js:231 MapPage i ...

Is it possible for TypeScript to convert objects while preserving type annotations?

Apologies for my limited English skills, but I will do my best to explain my dilemma. I am looking to create a TypeScript function that can replace the keys of an Object. For example: interface Target { name: string; ID: number; } // The functio ...

Implementing global user authentication state with Zustand in Next.js version 13.4.9

I'm grappling with incorporating zustand into my Next.js 13.4.9 app, specifically for managing global authentication state. Below is the code snippet I have in my application: zustand store: // /src/store/AuthStore.ts import { create } from 'zu ...

Tips on configuring a segment in an Angular 6 route

Question: I am looking to configure a specific segment after the user logs in, for example http://localhost:4200/#/{dynamic name}/{dynamic name}/app/... However, I am facing an issue when navigating to /app/... across the application. Is there a way to a ...

tips on how to export an object with a specified data type

I need to restrict the type of exported function for my module type Request = ItemGetRequest | ItemUpdateRequest<Property> type Response = Property | ItemUpdateResponse<Property> type Handlers = {[key: string]: Handler<Request, Response> ...

A guide on combining multiple arrays within the filter function of arrays in Typescript

Currently, I am incorporating Typescript into an Angular/Ionic project where I have a list of users with corresponding skill sets. My goal is to filter these users based on their online status and skill proficiency. [ { "id": 1, ...

Is it possible to regulate the type of a class that has not yet been instantiated?

Is there a method in typescript to restrict the type of an uninstantiated class? I am looking to specify that only classes which inherit from Repository can be accepted by the addRepository method without actually creating an instance of the class (its co ...

Discovering the best method to retrieve user details (email address) following a successful login across all pages or components within Angular

Discovering the world of Angular and TypeScript is quite exciting. In my Angular project, I have 8 pages that include a login and registration page. I'm facing an issue where I need to access the user's email data on every page/component but the ...

Ways to define a static variable within a function using Typescript

There is a common approach to declaring a Static Variable or Function within a Class, demonstrated here: class SomeClass(){ static foo = 1; static fooBar(){ return ++SomeClass.foo; } } However, is it possible to declare a Static Local Variable ...

The switch statement and corresponding if-else loop consistently produce incorrect results

I'm currently facing an issue where I need to display different icons next to documents based on their file types using Angular framework. However, no matter what file type I set as the fileExtension variable (e.g., txt or jpg), it always defaults to ...

Attempting to build a table within a table structure

My goal is to create a nested table structure similar to this image: https://i.sstatic.net/v6lZo.png The number of months, topics, and arguments for each topic can vary as they are retrieved from a database. I have attempted to implement this functionali ...

Tips for integrating tsconfig with webpack's provide plugin

In my project, I have a simple component that utilizes styled-components and references theme colors from my utils.tsx file. To avoid including React and styled-components in every component file, I load them through WebpackProvidePlugin. Everything works ...

Guide on integrating angular-schema-form into an Ionic 2.0 project using typescript

Recently, I embarked on creating an app with Ionic from scratch and decided to integrate the framework. While I faced no issues executing the example on a webpage, I encountered difficulties when attempting to do so with Ionic. To kickstart the project, ...

Typescript: Unfiltering a string array

Seeking assistance with TypeScript syntax as a beginner. I'm struggling to refactor this code in order to retrieve the full list of serviceBranches. Currently, there is filtering and mapping resulting in only one serviceBranch being returned from our ...

Guide on how to prevent click events when a checkbox is not selected in Angular 2

A click event is being used on a ul element with a checkbox below it. When the checkbox is checked, the list should be enabled and the click event should work. If the checkbox is unchecked, the list should be disabled and the click event should not work. ...

Preventing data loss in an Ionic array - encountering issues with using this.array.push

When attempting to use the storage get method to fill the array storedArr = [], I encounter the error message .push is not a function: storedArr = this.storage.get('stored') ? this.storage.get('stored').then((e) => {e}) : []; The c ...

What causes the RxJS pipe not to run in ngOnInit when the Observable is initialized at the class level?

Why doesn't the pipe in the ngOnInit method get triggered when the Observable is initialized at the class property declaration level and unwrapped by the async pipe? Although I am aware that I can initialize the Observable in the ngOnInit method itse ...

Personalized context hook TypeScript

I have been experimenting with a custom hook and the context API, based on an interesting approach that I found in this repository. However, I encountered an error when trying to use it with a simple state for a number. Even though I wanted to create a mo ...

Tips for triggering the update of index.view when the Save command is triggered within an active dialog

When I try to save in an open dialog using the Save command, the parent index.view does not update. However, everything works fine when using the SaveAndClose command. This was tested on the Product object at https://github.com/alex-kukhtin/A2v10.Web.Sampl ...

Creating offspring within offspring

I am currently facing a problem that I believe should be easy to solve. The issue revolves around rendering a component on a particular page. I have set a layout for all child components under the dashboard, but I am uncertain if another layout is needed f ...