Home > Enterprise >  How to filter an array inside an object?
How to filter an array inside an object?

Time:09-05

I'm struggling to filter an array inside an object on a condition (in my case filter if value1 <> value2 and toggle is true)

myObject = { 
    value: 1, 
    capacitiesArray: [{value1: 10, value2: 10}, {value1: 10, value2: 20}] 
}

so my output should be

filtredObject = { 
    value: 1, 
    capacitiesArray: [{value1: 10, value2: 20}] 
}

I created this function called "filterObject", that have in parameter "myObject" et "toggle"(if toggle true then filer "capacitiesArray" else don't filter "capacitiesArray"

I tried to do it by doing that, but it's doesn't seem to work :(

I think I'm having an issue with object mutation

function filterObject(myObject: MyObject, toggle: boolean): MyObject {
if(toggle) {
  const rows = myObject.capacitiesArray; 
  const capacitiesArray = rows.filter((row) => row.value1 !== row.value2); 
  myObject.capacitiesArray = capacitiesArray; 
  return myObject; 
  } 
return myObject; 
}

Here's a link for the code to unit test the function https://stackblitz.com/edit/github-test-run-draft-gczdsg?file=src/app/app.component.spec.ts

in app.component.spec.ts

the second test "filterRowOnCosCoeValue should filter operationalCapacities when toggle on" passes (that's fine, since the expected result is "expectedOperationalNoticeMock")

but it should not pass when I provide "operationalNoticeMock" as expected object result (it passes anyways giving a false positive result)

Any help/suggestion ? :) Thank you!

EDIT: add details for false positive test passing

CodePudding user response:

This is as you pointed out due to object mutation issues. As you probably know Objects in Javascript are by reference. If you mutate the Object a simple comparison wont show you any cahnge, so you have to perform a deep comparison.

Try the following in your test:

  it('filterRowOnCosCoeValue should filter operationalCapacities when toggle on', () => {
    const expectedResult = JSON.stringify(operationalNoticeMock);
    const result = JSON.stringify(filterObject(operationalNoticeMock, true));
    expect(result).toEqual(expectedResult);
  });

I have forked the stackblitz

EDIT

Right now the test is failing but if you replace the value with expectedOperationalNoticeMock will pass.

Change this line:

const expectedResult = JSON.stringify(operationalNoticeMock);

By this one:

const expectedResult = JSON.stringify(expectedOperationalNoticeMock);

It will pass as expected.

CodePudding user response:

I tried it and it works for me:

let obj = {
  h: "any",
  arr: [{
    value1: 10,
    value2: 10
  }, {
    value1: 10,
    value2: 20
  }]
}

let rows = obj.arr;
obj.arr = rows.filter(v => v.value1 !== v.value2);

console.log(obj);

  • Related