0

I am trying to do some basic filtering of some of my API results, to not appear if the store already contains that data in its parent object (think of this scenario as you're updating the parent client side, but you've yet to post it to the server; so you don't need to see data that you might post up).

I am using the includes method, and it is returning false, though it makes no sense to me what so ever. For example:

Here is my data for existing Ids after adding the extra element:

0: {athleteId: "246f3ff3-a889-4027-9643-0f376eeba4ce"}
1: {athleteId: "d8564df2-1464-4547-b418-d1c4c75fe1fc"}
2: {athleteId: "e36db0a1-4fe9-482c-910c-fc8b87770401"}
3: {athleteId: "71630dfc-f03a-45c0-b72c-24190658fa76"}

As you can see, it is an array with 4 elements, okay so far so good.

Then for testing purposes I do

console.log("Exists: ", existingIds!.includes({athleteId: "71630dfc-f03a-45c0-b72c-24190658fa76"}))

This returns false.

However, if I replace the object notation there with say existingIds[3] then it will return true. The full code is as follows:

var apiData = await Agent.Coaches.availableAthletes(id);

            if(this.coach !== null) {

                var existingIds = this.coach.assignedAthletes?.map((x) => (
                    {
                        athleteId: x.athleteId
                    }
                ));
                console.log("Existing Ids: ", existingIds);

                if(existingIds?.length === 4) {
                    console.log("Test: ",  existingIds[3])
                    console.log("Exists: ", existingIds!.includes({athleteId: "71630dfc-f03a-45c0-b72c-24190658fa76"}))
                }

                apiData = apiData.filter(x => !existingIds!.includes({athleteId: x.athleteId})) 
                //this.coach.assignedAthletes!.filter(x => apiData.includes(x));
            }

What exactly am I doing wrong here? The idea would be simple to implement in C# (which is sorta what I am trying to do) where I am just getting the IDS so the map function would be the equivalent of like

assignedAthletes.Select(x => { x.athleteId });

then for the filter I would just do:

finalData = finalData.Where(x => !assignedAthletes.Contains(x.athleteId))

I've done this many times in C# and never faced the same odd behavior as I am in JS

SomeStudent
  • 2,146
  • 1
  • 18
  • 31
  • The object you're passing into includes is a different reference to the object in your array. Same reason why `{a: 1} === {a: 1}` gives `false` – Nick Parsons Jun 18 '20 at 03:10
  • I thought so, but I was under the impression that JS is less stringent with that (the whole if it looks like a duck analogy) and that it would instead be looking at the data points to figure out if it exists – SomeStudent Jun 18 '20 at 03:11
  • includes works for primitive arrays not array of objects. – M A Salman Jun 18 '20 at 03:13
  • 3
    What you can do instead is use `.some()`, to check if an object in your array meets the condition specified in the callback: `existingIds.some(({athleteId}) => athleteId === "71630dfc-f03a-45c0-b72c-24190658fa76");` – Nick Parsons Jun 18 '20 at 03:15
  • @NickParsons yep, exactly what I did thanks to the link you left when the question was marked as duplicated. I am using it as follows: apiData = apiData.filter((x, index) => !this.coach?.assignedAthletes?.some(x => { return JSON.stringify(apiData[index]) === JSON.stringify(x) })) – SomeStudent Jun 18 '20 at 03:16
  • @SomeStudent that should work. I personally find the second answer better: [Javascript's .includes function not working correctly with array of objects](https://stackoverflow.com/a/50371220) for your case. JSON.stringify is good for checking if _all_ the properties and values match, whereas using destructuring to check if the `athleteId` matches a given string will just check that the `athleteId` matches. Which I think would also improve efficiency a little as you're not stringifying objects. But I guess either way works at the end of the day :P – Nick Parsons Jun 18 '20 at 03:22
  • 1
    True, I will most certainly update it to the more efficient approach. Thank you for the assist :) – SomeStudent Jun 18 '20 at 03:28
  • Note that `JSON.stringify()` will not necessarily compare objects accurately, as the ordering of properties is not guaranteed to be the same for two objects that otherwise "look" the same. Also, not all objects can be stringified. – Pointy Jun 18 '20 at 12:47

0 Answers0