0

I have an array with objects inside. I get the array from my firestore database. When I get the array, I check if my user has any of the objects. When I check this using includes() I get false as a return, but the array clearly has the object. What can be the issue?

Check:

            const querySnapshot = await getDocs(colRef);

            querySnapshot.forEach(async(badge) => {
                console.log(userData.obtainedBadges)
                if(!userData.obtainedBadges.includes(badge.data())){                        
                    console.log(badge.data())
                    console.log("not includes")
                    setObtainableBadges(prev => {
                        return [...prev, badge.data()]
                     })
                } else {
                    console.log("includes")
                    setUserBadges(prev => {
                        return [...prev, badge.data()]
                     })
                }
            })

For example one of the objects I check( badge.data() ) :

Object { id: 1, desc: "Play 5 games.", type: "games", reward: 10, condition: 5, img: "/trophies/firsttrophy.png", name: "The First Games" }

querySnapshot Array:

Array(9) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…} ]
​
0: Object { img: "/trophies/firsttrophy.png", type: "games", name: "The First Games", … }
​
1: Object { id: 2, type: "games", name: "The Beginner", … }
​
2: Object { name: "The Big Brain", id: 50, type: "games", … }
​
3: Object { condition: 50, id: 4, desc: "Play 50 games.", … }
​
4: Object { name: "Noob", reward: 10, img: "/trophies/noobmedal.png", … }
​
5: Object { id: 6, reward: 10, desc: "Reach a minimum high score of 2000.", … }
​
6: Object { condition: 3000, desc: "Reach a high score of 3000.", name: "Unstoppable", … }
​
7: Object { desc: "Reach a score of 0 in any gamemode.", id: 9, reward: 25, … }
​
8: Object { type: "easteregg", condition: "easteregg", desc: "Find an easter egg!", … }
​
length: 9
​
<prototype>: Array []

You can see, that my object is the first element in the array. But for some reason, includes() returns false.

Jaydendev
  • 123
  • 2
  • 14

1 Answers1

1

When you compare two objects in JavaScript it is not enough that their keys and values match. All objects have internal ids and therefor two objects or arrays with the same keys and values will in a regular comparison like == still return false. See example :

const object1 = {test:'test'}
const object2 = {test:'test'}
console.log(object1 == object2)
The same goes for arrays, maps, sets and all non-primitive values in JavaScript. It is however possible to compare objects, arrays non-primitives but only by comparing all their properties. This can get really complicated, as objects can contain other non-primitives and to make a general use function you would need to make a recursive function that can handle any JavaScript type, which would be total overkill for you situation. In a case like this one you should check on a unique value, id for example, instead of comparing the whole objects. Something like this :

const badge_in_user_data = userData.obtainedBadges.some(badge => badge.id == badge.data().id)
ksav
  • 20,015
  • 6
  • 46
  • 66
Jip Helsen
  • 1,034
  • 4
  • 15
  • 30