'Creating a JavaScript object that grabs each array item and collates it

I am trying to create a JavaScript object that grabs each services array in BusinessData, and then collates it as follows:

services: [
                {
                    id: 1,
                    businessId: 1,
                    title: 'Brake Fluid Refresh'
                },
                {
                    id: 2,
                    businessId: 1,
                    title: 'Diagnostics'
                },
                {
                    id: 3,
                    businessId: 1,
                    title: 'Coolant Refresh'
                },
                {
                    id: 4,
                    businessId: 1
                    title: 'Oil Change'
                },
                {
                    id: 5,
                    businessId: 1,
                    title: 'MOT'
                },
                {
                    id: 6,
                    businessId: 1,
                    title: 'Summer Check'               
                },
                {
                    id: 7,
                    businessId: 1,
                    title: 'Winter Check'                   
                }           
            ]

This is my code so far:

var businessData = [
        {
            id: 1,
            categoryId: 1,
            name: 'Japan Center Garage',
            services: [
                {
                    id: 1,
                    businessId: 1,
                    title: 'Brake Fluid Refresh'
                },
                {
                    id: 2,
                    businessId: 1,
                    title: 'Diagnostics'
                }               
            ]
        },
        {
            id: 2,
            categoryId: 1,
            name: 'Rex Garage',
            services: [
                {
                    id: 3,
                    businessId: 1,
                    title: 'Coolant Refresh'
                },
                {
                    id: 4,
                    businessId: 1
                    title: 'Oil Change'
                }   
            ]
        },
        {
            id: 3,
            categoryId: 1,
            name: 'Mission & Bartlett Garage',
            services: [
                {
                    id: 5,
                    businessId: 1,
                    title: 'MOT'
                },
                {
                    id: 6,
                    businessId: 1,
                    title: 'Summer Check'               
                },
                {
                    id: 7,
                    businessId: 1,
                    title: 'Winter Check'                   
                }               
            ]
        }               
    ]

    return {
        getAllCategories: function () {
            return categoryData;
        },

        getAllServices: function () {
            var servicesData = {
                services: []
            };
            for(var i = 0; i < businessData.length; i++) {
                if(businessData[i].services) {
                    servicesData['services'].push(businessData[i].services)
                }
            }
            return servicesData;
        },

        getAllBusinesses: function () {
            return businessData;
        },
    }
}])

It doesn't work very well, and produced an array that I can't seem to access in my view after calling it from my controller:

<div class="item item-divider">
Service
</div>
<ion-list>
<ion-item ng-repeat="item in serviceList | orderBy:'title'">
  <p>{{item.title}}</p>
</ion-item>
</ion-list>
<div ng-if="item !== undefined && !item.length" class="no-results">
<div class="item" style="border-top: 0px">
    <p>No Results</p>
</div>
</div>

Update

serviceList is called from my the controller:

$scope.serviceList = ServicesData.getAllServices();

What is going wrong here?



Solution 1:[1]

var services = [];

businessData.forEach(function (business) {
    Array.prototype.push.apply(services, business.services);
});

You are almost there, but you are pushing array of services to an array. By using Array.prototype.push.apply, we are instead pushing services to an array. Which eventually gives you the result you want :)

Solution 2:[2]

You can use lodash for that, and you better add it to your toolkit in general.

Here is how it will look with lodash:

_.flatMap(businessObject, (d) => d.services)

Or even

_.flatMap(businessObject, "services")

To make it little bit more verbose, you are doing map and then flatten:

var mapped = _.map(businessObject, "service")
var services = _.flatten(mapped)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Prashant
Solution 2