I have a function, which maps an array with underscore.  Here is the function:
var services = _.map(userCopy.get('services'), function (service) {
    if (service.service_selected === true) {
        return service;
    }
});
My problem is that when the conditional === false, then I get undefined put into services.  Of course I can remove the undefined, but that is ugly and I just want to use map correctly.  How do I fix this?
To not return undefined values from the map() method, you have to explicitly return a value from the callback function you passed to map() .
A variable that has not been assigned a value is of type undefined . A method or statement also returns undefined if the variable that is being evaluated does not have an assigned value. A function returns undefined if a value was not returned .
Updated my answer... This solved my problem
    var missingParamsArray = _.map(requiredParams, function (val, param) {
        if (val) {
            if (!req.user[param]) {
                return param;
            }
        }
    });
    var missingParams = _.filter(missingParamsArray, Boolean);
missingParams can also be written as
var missingParams = _.filter(missingParamsArray, function (param) {
       return param !== undefined;
    });
                        _.map uses whatever the function returns, to build the result. If a function doesn't return anything explicitly, JavaScript returns undefined. That's why the result of _.map has undefined whenever the condition fails.
What you actually need, is a _.filter
var services = _.filter(userCopy.get('services'), function(service) {
    return service.service_selected === true;
});
_.filter accepts a collection and a predicate function. It applies the predicate function to each and every value of the collection and if the function returns true, that element will be included in the result, if the function returns false, that element will be skipped.
Note: You can actually use _.matcher, along with _.filter, like this
var isServiceSelected = _.matcher({
    service_selected: true;
});
var services = _.filter(userCopy.get('services'), isServiceSelected);
This will be very useful if you are going to filter based on service_selected: true condition more than once. If it is just a one-time thing, then _.where shown below would be better alternative.
You can also use _.where, which can return the objects only if the current object contains all the key-value pairs listed, like this
var services = _.where(userCopy.get('services'), {
    service_selected: true;
});
Now, all the service objects will be returned which have service_selected attribute value as true.
Demo:
function display(heading, data) {
    var json = JSON.stringify(data, null, 4);
    document.body.appendChild(document.createElement('h3')).innerHTML = heading;
    document.body.appendChild(document.createElement('pre')).innerHTML = json;
}
var data = [{
    "name": "auth",
    "service_selected": true
}, {
    "name": "authorization",
    "service_selected": false
}, {
    "name": "faltu",
    "service_selected": true
}];
display("_.filter", _.filter(data, function (service) {
    return service.service_selected === true;
}));
display("_.matcher", _.filter(data, _.matcher({
    service_selected: true
})));
display("_.where", _.where(data, {
    service_selected: true
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With