user18113903
user18113903

Reputation:

Recursion forEach does not update my values? using Javascript

I need to update my values with recursion but my loop no work? First check code:

  const minusItem = (items) => {
    console.log("items", items);
    if (items.length > 0) {
      items.forEach((orgUnit) => {
        orgUnit.dashCheck = true;
        orgUnit.allChildItemChecked = false;
        if (orgUnit.parentNode.unitId) {
          minusItem(orgUnit.parentNode); //recursion
        }
      });
    }
  };

items is array but worst of all sometimes an object is sent but there is an if that says

items.length > 0

here I filter only strings that have length> 0

array is like

[
 { 
 unitId: 1 ,
 title: "Test 1 " ,
 dashCheck: false,
 allChildItemChecked: false
 parentNode: {
    unitId: 2 ,
    title: "Test 2" ,
    dashCheck: false,
    allChildItemChecked: false, 
    parentNode: { 
       unitId: 3 ,
       title: "Test 3" ,
       dashCheck: false,
       allChildItemChecked: false, 
        }
      } 
   }
]

of these parentNode can have 100....

I need to loop thought each and set

    orgUnit.dashCheck = true;
    orgUnit.allChildItemChecked = false;

Upvotes: 1

Views: 266

Answers (2)

trincot
trincot

Reputation: 350270

You only have one array. The nested objects are not arrays, so they don't have a length property.

The forEach should be moved outside of the recursive function, where it will execute only once:

const minusItem = (item) => {
    item.dashCheck = true;
    item.allChildItemChecked = false;
    if (item.parentNode) { // Just check if there is a parent node
        minusItem(item.parentNode); //recursion 
    }
};

let data = [{ 
 unitId: 1 ,
 title: "Test 1 " ,
 dashCheck: false,
 allChildItemChecked: false,
 parentNode: {
    unitId: 2 ,
    title: "Test 2" ,
    dashCheck: false,
    allChildItemChecked: false, 
    parentNode: { 
       unitId: 3 ,
       title: "Test 3" ,
       dashCheck: false,
       allChildItemChecked: false, 
    }
  } 
}];

data.forEach(minusItem); // The only place to perform a loop
console.log(data);

Moving the iteration inside a function:

If you need the main function to be minusItem and to be called on the original array, then make a second function for the recursive part:

const minusItem = (items) => items.forEach(minusItemRecur);

const minusItemRecur = (item) => {
    item.dashCheck = true;
    item.allChildItemChecked = false;
    if (item.parentNode) { // Just check if there is a parent node
        minusItemRecur(item.parentNode); //recursion 
    }
};

let data = [{ 
 unitId: 1 ,
 title: "Test 1 " ,
 dashCheck: false,
 allChildItemChecked: false,
 parentNode: {
    unitId: 2 ,
    title: "Test 2" ,
    dashCheck: false,
    allChildItemChecked: false, 
    parentNode: { 
       unitId: 3 ,
       title: "Test 3" ,
       dashCheck: false,
       allChildItemChecked: false, 
    }
  } 
}];

minusItem(data);
console.log(data);

Upvotes: 2

A1exandr Belan
A1exandr Belan

Reputation: 4780

Lodash cloneDeepWith if you don't mind

const data = [{unitId: 1 ,title:"Test 1 ",dashCheck: false,allChildItemChecked:false,parentNode:{unitId:2,title:"Test 2" ,dashCheck:false,allChildItemChecked:false,parentNode:{unitId:3 ,title:"Test 3",dashCheck:false,allChildItemChecked:false}}}];

const result = _.cloneDeepWith(data, (val, key) => {
    if (key === 'dashCheck') return true;
    if (key === 'allChildItemChecked') return false;       
});

console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

Upvotes: 1

Related Questions