0

Interface:

export interface User {
  userId: number;
  userName: string;
  emailId: string;
  role: string;
}

export interface UserState {
  users: User[];
  _users: User[];
}

export const initialUserState: UserState = {
  users: [],
  _users: []
};

Signal store:

import { httpResource } from '@angular/common/http';
import { signalStore, withComputed, withProps, withState } from '@ngrx/signals';
import { initialUserState, User } from './user.slice';

const basePath = 'https://api.freeprojectapi.com/api/BusBooking';
const getAllUsers = `${basePath}/GetAllUsers`;

export const USERSTORE = signalStore(
  withState(initialUserState),
  withProps(() => {
    const users = httpResource<User[]>(() => getAllUsers);
    return { _users: users };
  }),
  withComputed((store: { users: User[]; _users: any }) => ({
    users: () => store._users.value() ?? []
  }))
);

I am getting withComputed errors as:

Argument of type '(store: { users: User[]; _users: any; }) => { users: () => any; }' is not assignable to parameter of type '(store: { users: Signal<User[]>; _users: (() => User[]) & { [SIGNAL]: unknown; } & HttpResourceRef<User[] | undefined>; }) => { users: () => any; }'.
  Types of parameters 'store' and 'store' are incompatible.
    Type '{ users: Signal<User[]>; _users: (() => User[]) & { [SIGNAL]: unknown; } & HttpResourceRef<User[] | undefined>; }' is not assignable to type '{ users: User[]; _users: any; }'.
      Types of property 'users' are incompatible.
        Type 'Signal<User[]>' is not assignable to type 'User[]'.ts(2345)

2 Answers 2

2

Refer to Defining Store Properties example, your withComputed function to access the state signal, properties and returning the dictionary with computed signals as below:

withComputed(({ users, _users }) => ({
  users: computed(() => _users() ?? [])
}))

Or

withComputed((store) => ({
  users: computed(() => store._users() ?? [])
}))
Sign up to request clarification or add additional context in comments.

Comments

0

The code you provided needs to be corrected. You should try the below changes instead.

The _users should be a HttpResourceRef, because you are assigning a httpResource to it.

export interface User {
  userId: number;
  userName: string;
  emailId: string;
  role: string;
}

export interface UserState {
  users: User[];
  _users: HttpResoureRef<User[] | undefined> | null; // <------- changed here!
}

export const initialUserState: UserState = {
  users: [],
  _users: null
};

Now change your store to access the .value() of the resourceRef.

import { httpResource } from '@angular/common/http';
import { signalStore, withComputed, withProps, withState } from '@ngrx/signals';
import { initialUserState, User } from './user.slice';

const basePath = 'https://api.freeprojectapi.com/api/BusBooking';
const getAllUsers = `${basePath}/GetAllUsers`;

export const USERSTORE = signalStore(
  withState(initialUserState),
  withProps(() => ({
    _users: httpResource<ApiResponse>(() => getAllUsers),
  })),
  withComputed((store) => ({
    users: () => store._users?.value() ?? []
  }))
);

2 Comments

is it a way to achieve this, without using pipe ? look here: stackblitz.com/edit/angular-atswfomf?file=src%2Fmain.ts
Like this stackblitz?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.