1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

Setting custom primary key with NgRx signal store withEntities

Discussão em 'Angular' iniciado por Levente Vági, Junho 19, 2025.

  1. Problem


    I have an ngrx/signalStore that contains fruits as entities. For proper usage of the signalStore, you need to have an id field in the Fruit class, but the API I use retrieves fruits that have a field fruitId. Is there a way to tell the store that it will be the primary key for the class instead of introducing a duplicated field named id?

    Here is my store:

    export const FruitStore = signalStore(
    { providedIn: 'root' },
    withEntities<Fruit>(),
    withMethods((
    store,
    fruitService = inject(FruitService),
    ) => ({
    loadFruits: rxMethod<void>(
    pipe(
    exhaustMap(() => {
    return fruitService.getFruits().pipe(
    tapResponse({
    next: (fruits) => {
    patchState(store, setAllEntities(fruits);
    },
    error: (error: { message: string }) => {
    console.log(error.message);
    }
    }),
    );
    }),
    )
    ),
    })),
    withHooks({
    onInit({ loadFruits }) {
    loadFruits();
    }
    }),
    );


    My Fruit class:

    export class Fruit {
    fruitId: number;
    name: string;
    imageURL: string;
    }

    Current solution


    My current solution is to add a duplicated field to the class (Fruit class comes from the API generated with OpenAPI, so I can not change it). But I'm not fully satisfied with this solution. Do you have any ideas to improve it?

    export type WithId<T> = T & { id: number };


    Changes in the store:

    export const FruitStore = signalStore(
    { providedIn: 'root' },
    // Extend Fruit class 'WithId'
    withEntities<WithId<Fruit>>(),
    withMethods((
    store,
    fruitService = inject(FruitService),
    ) => ({
    loadFruits: rxMethod<void>(
    pipe(
    exhaustMap(() => {
    return fruitService.getFruits().pipe(
    tapResponse({
    next: (fruits) => {
    // Add the duplicated field
    patchState(store, setAllEntities(fruits.map(fruit => ({ ...fruit, id: fruit.fruitId })));
    },
    error: (error: { message: string }) => {
    console.log(error.message);
    }
    }),
    );
    }),
    )
    ),
    })),
    withHooks({
    onInit({ loadFruits }) {
    loadFruits();
    }
    }),
    );

    Continue reading...

Compartilhe esta Página