Search code examples
javascriptangulartypescriptngrx-store

Recursive delete from ngrx store


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.