6

The Warning is here

enter image description here

https://github.com/rokudo5262/phone this is my project
i want to load the list of brands in smart table but get the warning
i try to fix but the warning is still there please help
Brands-features.selector.ts

import { createFeatureSelector } from '@ngrx/store';
import { State, FeatureKey } from '../reducers';

export const selectBrandsState = createFeatureSelector<State>(FeatureKey);

Brands.selector.ts

import { createSelector } from '@ngrx/store';
import { selectBrandsState } from './brands-features.selector';
import { BrandsReducer } from '../reducers';
import { brandAdapter } from '../states/brands.state';

export const selectBrandEntitiesState = createSelector(
  selectBrandsState,
  state => state[BrandsReducer.brandsFeatureKey],
);

export const {
  selectIds: selectBrandIds,
  selectEntities: selectBrandEntities,
  selectAll: selectAllBrands,
  selectTotal: selectTotalBrands,
} = brandAdapter.getSelectors(selectBrandEntitiesState);

export const BrandSelectors = {
  selectBrandEntitiesState,
  selectBrandIds,
  selectBrandEntities,
  selectAllBrands,
  selectTotalBrands,
};
export const selectCurrentBrand = (brand_id) => createSelector(
  selectBrandEntities,
  (brand) => brand[brand_id],
)

selector/index.ts

export * from './brands-features.selector';
import * as BrandsSelector from './brands.selector';

export {
    BrandsSelector,
};

Brand.reducer.ts

import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';
import { IBrand } from '../../../@core/data/brands';

export interface BrandsState extends EntityState<IBrand> {
    selectedBrandID: number | string | null;
}
export const brandAdapter: EntityAdapter<IBrand> = createEntityAdapter<IBrand>({
    selectId: (brand: IBrand) => brand.brand_id,
    sortComparer: null,
});

export const brandInitialState: BrandsState = brandAdapter.getInitialState({
    selectedBrandID: null,
    entities: {
        0: {},
    },
});
satanTime
  • 12,631
  • 1
  • 25
  • 73
TrinhQuangTruong
  • 105
  • 1
  • 11

3 Answers3

6

createEntityAdapter has a selectId function which expects an id field in your element.

Example:

[
    { "id": 1, "name": "Lorem ipsum 1" },
    { "id": 2, "name": "Lorem ipsum 2" }
]

But, your elements have a custom id field like this one:

[
    { "elementId": 1, "name": "Lorem ipsum 1" },
    { "elementId": 2, "name": "Lorem ipsum 2" }
]

To solve the issue, i've overwritten the selectId method from the createEntityAdapter as follows:

const elementAdapter = createEntityAdapter({
  selectId: (e) => e.elementId
});

You can find more info here: https://redux-toolkit.js.org/api/createEntityAdapter

3

I found the problem, turn out the problem is a '''brand_id''' in my Brand Table, entity.Property(e => e.BrandId).HasColumnName("brand_id"); and brand_id in my Ibrand interface not in the code. so i change everything to brandCode and the warning is gone.


            modelBuilder.Entity<Brands>(entity =>
            {
                entity.HasKey(e => e.BrandCode)

                entity.Property(e => e.BrandCode).HasColumnName("brandCode");

                entity.Property(e => e.BrandName)
                    .HasColumnName("brandName")
                    .HasMaxLength(255);

                entity.Property(e => e.CreatedBy)
                    .HasColumnName("createdBy")
                    .HasMaxLength(255);

                entity.Property(e => e.CreatedDateTime)
                    .HasColumnName("createdDateTime")
                    .HasColumnType("datetime");

                entity.Property(e => e.Deleted).HasColumnName("deleted");

                entity.Property(e => e.Remark)
                    .HasColumnName("remark")
                    .HasMaxLength(255);

                entity.Property(e => e.Status)
                    .HasColumnName("status")
                    .HasMaxLength(255);

                entity.Property(e => e.UpdatedDateTime)
                    .HasColumnName("updatedDateTime")
                    .HasColumnType("datetime");

                entity.Property(e => e.Updatedby)
                    .HasColumnName("updatedby")
                    .HasMaxLength(255);
            });
export const brandAdapter: EntityAdapter<IBrand> = createEntityAdapter<IBrand>({
    selectId: (brand: IBrand) => brand.brandCode,
    sortComparer: null,
});
export interface IBrand {
    brandCode: number;
    brandName: string;
    status: string;
    remark: string;
    deleted: boolean;
    createdBy?: string;
    createdDateTime?: Date;
    lastUpdatedBy?: string;
    lastUpdatedDateTime?: Date;
}
TrinhQuangTruong
  • 105
  • 1
  • 11
1

I guess the problem is in selectCurrentBrand, might you share how you use it?

export const selectCurrentBrand = (brand_id) => createSelector(
  selectBrandEntities,
  (brand) => brand[brand_id],
)

if you do it like this.store.select(selectCurrentBrand, 123), then the right way is

export const selectCurrentBrand = createSelector(
  selectBrandEntities,
  (brand, brand_id) => brand[brand_id],
)

the selector

this.roomgroup$ = this.store.pipe(select(RoomGroupSelectors.selectCurrentRoomGroup, this.id$))
satanTime
  • 12,631
  • 1
  • 25
  • 73
  • i used that to call for detail component by id like this
    ```export class RoomGroupDetailComponent implements OnInit { roomgroup$; id$: number; constructor( private router: ActivatedRoute, private store: Store ) { this.id$ = +this.router.snapshot.params.id; this.roomgroup$ = this.store.pipe(select(RoomGroupSelectors.selectCurrentRoomGroup(this.id$))); } ngOnInit() { this.store.dispatch(RoomGroupsActions.getRoomGroup({ roomgroups: [] })); }``` and i think my problem is relate to selectAlll
    – TrinhQuangTruong May 18 '20 at 14:01
  • I see, I've updated the answer, you should select it like that: `this.roomgroup$ = this.store.pipe(select(RoomGroupSelectors.selectCurrentRoomGroup, this.id$))` – satanTime May 18 '20 at 14:03
  • i try the ```selectCurrentBrand``` it's normal and the warning is still there – TrinhQuangTruong May 18 '20 at 14:35
  • then try instead of `brandAdapter.getSelectors(selectBrandEntitiesState)` this one `brandAdapter.getSelectors(selectBrandsState)`. Also might you share how you connect with the StoreModule? Perhaps it can bring light. – satanTime May 18 '20 at 14:37
  • i get the `problem` ```{ "Argument of type 'MemoizedSelector>' is not assignable to parameter of type '(state: object) => EntityState'.\n Type 'State' is missing the following properties from type 'EntityState': ids, entities", }``` – TrinhQuangTruong May 18 '20 at 14:52
  • I see that it's brands -> brands on the screenshot and curious whether it's correct. – satanTime May 18 '20 at 15:03
  • You can check a working example here: https://github.com/satanTime/ngrx-entity-relationship/tree/master/e2e/angular9/src/app/entity/store (check just users) try to compare file by file and it should solve the issue, I think the issue comes from selectors, but it's tough to say which one causes the issue. – satanTime May 18 '20 at 15:54