[Fixed] Recursive delete from ngrx store

Issue

I use Angular 10 and library ngrx store and I don’t understand how to recursively delete from ngrx store. In the store I have a nested array of objects. How do I recursively delete an object by id? When I try to delete using splice and function I got an error:

Cannot assign to read only property ‘0’ of object ‘[object Array]’

What am I doing wrong?

Data Example:

[
  {
    "id": 414,
    "name": "mail.ru",
    "is_main": true,
    "subdomains": [
      {
        "id": 423,
        "name": "en.mail.ru",
        "is_main": false,
        "subdomains": [
          {
            "id": 429,
            "name": "gw.mail1.ru",
            "is_main": false,
            "subdomains": [
              {
                "id": 426,
                "name": "gw.mail3.ru",
                "is_main": false,
                "subdomains": []
              }
            ]
          }
        ]
      },
      {
        "id": 425,
        "name": "gw.mail.ru",
        "is_main": false,
        "subdomains": []
      }
    ]
  }
]

Store reducer:

 case UserInfoActionTypes.UPDATE_DOMAINS_LIST: {
            return {
                ...state,
                domainsInfo: deleteItems(state.domainsInfo, [parseInt(action.payload.id, 10)]),
                errorMessage: null
            };
        }`

My Recursive function:

export function deleteItems(array, ids) {
    let i = array.length;
    while (i--) {
        if (ids.indexOf(array[i].id) !== -1) {
            array.splice(i, 1);
            continue;
        }
        array[i].subdomains && deleteItems(array[i].subdomains, ids);
    }
    return array;
}

Solution

So basically you need to create new objects for everything in state, deleteItems() could look like this:

export function deleteItems(array, ids) {
    let result = [];
    for(item of array) {
        if (!ids.includes(item.id)) {
            result.push({
              ...item,
              subdomains: deleteItems(item.subdomains, ids),
            })
        }
    }
    return result;
}

I’m not too familiar with ngrx, maybe I missed a detail.

Leave a Reply

(*) Required, Your email will not be published