Search code examples
angularngrxngrx-store

ngrx updateOne change ids array sorting


I have an index of Invoices loaded from API to the NGRX Store, When the user enters a single Invoice it updates the full details from the API.

the Issue is that the index order changed when I user Ngrx updateOne I find that the ids array moves the entity to the front when updating it.

This issue is known and should be solved on older Ngrx version (v10): https://github.com/ngrx/platform/issues/571

I'm using Ngrx version 12

When loading index

after updateOne

Index problem

Sort part on State

export const invoicesAdapter: EntityAdapter<InvoiceInterface> = createEntityAdapter<InvoiceInterface>({
  selectId: customizedInvoiceId,
  sortComparer: sortByCreatedAt 
});

export function customizedInvoiceId(a: InvoiceInterface): string {
  return a.id;
}

export function sortByCreatedAt(a: InvoiceInterface, b: InvoiceInterface): number {
  return a.createdBy?.toLocaleString().localeCompare(b.createdBy?.toLocaleString());
}

updateOne on Reducer

const _invoicesReducer = createReducer(
  initialInvoicesState,
  on(addInvoiceSuccess, (state, action) => {
    return invoicesAdapter.addOne(action.invoice, state);
  }),
  on(updateInvoiceSuccess, (state, action) => {
    return invoicesAdapter.updateOne(action.invoice, state);
  }),

...

Angular and Ngrx Packages

"dependencies": {
        "@angular/animations": "~12.2.0",
        "@angular/cdk": "^12.2.0",
        "@angular/common": "~12.2.0",
        "@angular/core": "~12.2.0",
        "@angular/forms": "~12.2.0",
        "@angular/material": "^12.2.0",
        "@angular/platform-browser": "~12.2.0",
        "@angular/platform-browser-dynamic": "~12.2.0",
        "@angular/router": "~12.2.0",
        "@angular/service-worker": "~12.2.0",
        "@ngrx/effects": "^12.5.1",
        "@ngrx/entity": "^12.5.1",
        "@ngrx/router-store": "^12.5.1",
        "@ngrx/store": "^12.5.1",
        "@ngrx/store-devtools": "^12.5.1",
        "@capacitor/android": "3.1.1",
...

Solution

  • the issue was on the sort function

    export function sortByCreatedAt(a: InvoiceInterface, b: InvoiceInterface): number {
      return a.createdBy?.toLocaleString().localeCompare(b.createdBy?.toLocaleString());
    }
    
    export function sortByCreatedAt(a: InvoiceInterface, b: InvoiceInterface): number {
      return b.createdAt?.toLocaleString().localeCompare(a.createdAt?.toLocaleString());
    }
    

    were the createdBy is an object