1

I'm using includes to check if an array of objects contains an object, but it always return false

const record = {
  id:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  key:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  number:1,
  priority:0
}

const selectedRows = [{
 id:"6c86e6c7-590a-44af-8492-1b83be1bf457",
 key:"6c86e6c7-590a-44af-8492-1b83be1bf457",
 number:1,
 priority:0
}]

alert(selectedRows.includes(record));

I don't understand why it works this way. How to make the check work properly?

Heidel
  • 3,174
  • 16
  • 52
  • 84

6 Answers6

4

That's because objects are only equal to themselves, and only themselves.*

console.log({x: 1} === {x: 1}); // outputs false

whereas

const obj = {x: 1}
console.log(obj === obj); // outputs true.

The array doesn't actually includes record, only an object that looks like it.

* Barring oddities like .valueOf() and .toString() etc.

Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness#A_model_for_understanding_equality_comparisons – Joe Iddon Sep 04 '18 at 09:01
  • I really did not want to conflate OP with the differences, it's all the same for objects, anyway. (If they were asking about NaN, it would have been a different answer) – Madara's Ghost Sep 04 '18 at 10:14
  • 1
    I see. I just provided that link since the `.includes` documentation uses the seem evaluation and it is explicit there. :) – Joe Iddon Sep 04 '18 at 10:16
3

It doesn't work cause u create two different objects, they are not the same.

It will return true in this case

const record = {
  id:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  key:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  number:1,
  priority:0
}

const selectedRows = [record]

alert(selectedRows.includes(record));

For check equallity of two objects, u can read answer to this question Object comparison in JavaScript So, in your case, u should iterate through array and try to compare your object with elements

Anton Krylov
  • 439
  • 1
  • 6
  • 17
2

Objects in Javascript are reference types. Meaning when they are compared, instead of comparing their properties one-by-one, the engine simply checks whether they point to same memory address.

In your case record object is not part of the array because during array initialization you create a separate object using the object initialization syntax {...}. Instead if you create the array using [records] you get the expected result:

const record = {
  id:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  key:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  number:1,
  priority:0
}

const selectedRows = [record];

// Result: true
alert(selectedRows.includes(record));

Another quick way to check this would be to modify record object and then compare it with the object in the array. You will notice that they are different, and that's because those two are two different objects:

const record = {
  id:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  key:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  number:1,
  priority:0
}

const selectedRows = [{
 id:"6c86e6c7-590a-44af-8492-1b83be1bf457",
 key:"6c86e6c7-590a-44af-8492-1b83be1bf457",
 number:1,
 priority:0
}];

console.log("Modifying properties in record:");
record.id = "0";
record.key = "0";
console.log("Record: ", record);
console.log("Array content: ", selectedRows);
Nisarg Shah
  • 14,151
  • 6
  • 34
  • 55
2

You can use some method which tests whether at least one element in the array passes the test.

This snippet is testing only id but multiple fields can also be included

const record = {
  id: "6c86e6c7-590a-44af-8492-1b83be1bf457",
  key: "6c86e6c7-590a-44af-8492-1b83be1bf457",
  number: 1,
  priority: 0
}

const selectedRows = [{
  id: "6c86e6c7-590a-44af-8492-1b83be1bf457",
  key: "6c86e6c7-590a-44af-8492-1b83be1bf457",
  number: 1,
  priority: 0
}]

let x = selectedRows.some((item) => {
  return record.id === item.id
})
console.log(x)
brk
  • 48,835
  • 10
  • 56
  • 78
1

const record = {
  id:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  key:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  number:1,
  priority:0
}

const selectedRows = [{
 id:"6c86e6c7-590a-44af-8492-1b83be1bf457",
 key:"6c86e6c7-590a-44af-8492-1b83be1bf457",
 number:1,
 priority:0
}]

//will alert the position of the element
//if -1 then element is not found
alert(selectedRows.findIndex(record => record.id === '6c86e6c7-590a-44af-8492-1b83be1bf457'));

You should check on id of element

Taranjeet Singh
  • 147
  • 1
  • 5
1

includes won't work for two different object. You can do something like this using Array#some perhaps:

const record = {
  id:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  key:"6c86e6c7-590a-44af-8492-1b83be1bf457",
  number:1,
  priority:0
}

const selectedRows = [{
 id:"6c86e6c7-590a-44af-8492-1b83be1bf457",
 key:"6c86e6c7-590a-44af-8492-1b83be1bf457",
 number:1,
 priority:0
}]

console.log(selectedRows.some(obj => JSON.stringify(obj) == JSON.stringify(record)));

Alternatively, you can use Array.findIndex to get the object index in the array.

BlackBeard
  • 10,246
  • 7
  • 52
  • 62