Search code examples
javascriptbackbone.jsunderscore.js

How to find an object within a JS collection by value


I am working with an API right now and I am using details[5].Value to target information in the following format:

details:
    "value":[
        { 
            "ID": "6",
            "Name": "Links",
            "Value": "URL"
        },
        { 
            "ID": "7",
            "Name": "Other",
            "Value": "URL"
        }
        etc
    ]

The problem is that the location inside of the JSON response is likely to change in the future, making my code obsolete and as the url has the potential to change as well, I cannot target that.

I want a way to target the value of url, mostly, because of this, by the value of the "Name" property. However, if I use something like

_.where(details, { Name: "Links" }).Value

It comes back as undefined. I am not sure if there would be another way to get to the information?


Solution

  • There are a couple points of confusion here.

    _.where returns an array:

    Looks through each value in the list, returning an array of all the values that contain all of the key-value pairs listed in properties.

    so your _.where(details, obj).Value will (almost) always give you undefined because an array is unlikely to have a Value property. _.findWhere on the other hand does return a single value:

    Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.

    Secondly, your details appears to look like:

    let details = {
        value: [
            { ID: '6', Name: 'Links', Value: 'URL' },
            { ID: '7', Name: 'Other', Value: 'URL' },
            ...
        ]
    }
    

    so you don't want to search details, you want to search details.value.

    Putting them together:

    _(details.value).findWhere({ Name: 'Links' }).Value
    

    or

    _.findWhere(details.value, { Name: 'Links' }).Value
    

    You could use Array.prototype.find (or Array.prototype.filter if you're looking for all matches) and write your own callback but you already have Underscore available so why bother? Furthermore, Backbone collections have findWhere and where methods and there are advantages to matching Backbone's overall terminology.