Home » Javascript » Adding object to parent array based on IDs using Lodash

Adding object to parent array based on IDs using Lodash

Posted by: admin November 1, 2017 Leave a comment

Questions:

So I’m having an issue – I’m getting some data from our internal API at work, but it’s not in the correct format I need to do what I have to do, so I have to make some transformations.

For this, I decided to use Lodash, however I’m stuck now.

Basically, I’m working with orders, but some of the products are addons to a parent product. I’ve managed so far to separate these two types of products, but I don’t know how I should go about adding an “addons” array as a child to the parent product with matching ID.

Here’s a basic stripped example of the output I’d like:

{
    "order": {
        "orderLines: [
            {
                "orderId": "foo",
                "addons" [
                    {
                        ...
                    }
                ]
            },
            {
                ...
            }
        ]
    }
}

And here’s my current code:

// TODO:
// Match addons to products based on "connectedTo" => "id", then add matching addons as a new array on parent object

// Base data
const data = {
    "order": {
        "shopOrderId": "19LQ89H",
        "createDate": "2017-10-24T13:09:22.325Z",
        "orderLines": [
            {
                "orderId": "19LQ89H",
                "product": {
                    "productName": "Paintball",
                },
                "id": "59ef3b8036e16f1c84787c1f",
                "stringId": "59ef3b8036e16f1c84787c1f"
            },
            {
                "orderId": "19LQ89H",
                "product": {
                    "productName": "Ølsmagning",
                },
                "id": "59ef3b8036e16f1c84787c20",
                "stringId": "59ef3b8036e16f1c84787c20"
            },
            {
                "orderId": "19LQ89H",
                "product": {
                    "productName": "CD-indspilning",
                },
                "id": "59ef3b8136e16f1c84787c21",
                "stringId": "59ef3b8136e16f1c84787c21"
            },
            {
                "orderId": "19LQ89H",
                "product": {
                    "productName": "Julefrokost",
                },
                "id": "59ef3b8236e16f1c84787c22",
                "stringId": "59ef3b8236e16f1c84787c22"
            },
            {
                "orderId": "19LQ89H",
                "product": {
                    "productName": "Hummer Limousine",
                },
                "id": "59ef3b8236e16f1c84787c23",
                "stringId": "59ef3b8236e16f1c84787c23"
            },
            {
                "orderId": "19LQ89H",
                "connectedTo": "59ef3b8236e16f1c84787c23",
                "product": {
                    "productName": "Ekstra kørsel 400",
                },
                "id": "59ef3b8236e16f1c84787c24",
                "stringId": "59ef3b8236e16f1c84787c24"
            },
            {
                "orderId": "19LQ89H",
                "connectedTo": "59ef3b8236e16f1c84787c23",
                "product": {
                    "productName": "Drikkevarer",
                },
                "id": "59ef3b8236e16f1c84787c25",
                "stringId": "59ef3b8236e16f1c84787c25"
            },
            {
                "orderId": "19LQ89H",
                "connectedTo": "59ef3b8236e16f1c84787c23",
                "product": {
                    "productName": "Drikkevarer",
                },
                "id": "59ef3b8236e16f1c84787c26",
                "stringId": "59ef3b8236e16f1c84787c26"
            },
            {
                "orderId": "19LQ89H",
                "connectedTo": "59ef3b8236e16f1c84787c22",
                "product": {
                    "productName": "Snaps ad libitum",
                },
                "id": "59ef3b8236e16f1c84787c27",
                "stringId": "59ef3b8236e16f1c84787c27"
            }
        ],
        "travelTimes": [
            {
                "id": "59ef3b8036e16f1c84787c1f-59ef3b8036e16f1c84787c20",
                "partyPlanFromEventId": "59ef3b8036e16f1c84787c1f",
                "partyPlanToEventId": "59ef3b8036e16f1c84787c20",
                "start": "2017-11-15T17:02:59",
                "end": "2017-11-15T17:30:00",
                "travelTimeString": "27 min.",
                "travelTimeMinutes": 28,
                "exceedsAvailableTime": false
            },
            {
                "id": "59ef3b8036e16f1c84787c20-59ef3b8136e16f1c84787c21",
                "partyPlanFromEventId": "59ef3b8036e16f1c84787c20",
                "partyPlanToEventId": "59ef3b8136e16f1c84787c21",
                "start": "2017-11-15T19:52:12",
                "end": "2017-11-15T20:00:00",
                "travelTimeString": "8 min.",
                "travelTimeMinutes": 8,
                "exceedsAvailableTime": false
            },
            {
                "id": "59ef3b8036e16f1c84787c20-59ef3b8236e16f1c84787c22",
                "partyPlanFromEventId": "59ef3b8036e16f1c84787c20",
                "partyPlanToEventId": "59ef3b8236e16f1c84787c22",
                "start": "2017-11-15T12:30:00",
                "end": "2017-11-15T13:00:00",
                "travelTimeString": "8 min.",
                "travelTimeMinutes": 8,
                "exceedsAvailableTime": true
            },
            {
                "id": "59ef3b8036e16f1c84787c20-59ef3b8236e16f1c84787c23",
                "partyPlanFromEventId": "59ef3b8036e16f1c84787c20",
                "partyPlanToEventId": "59ef3b8236e16f1c84787c23",
                "start": "2017-11-15T08:30:00",
                "end": "2017-11-15T09:00:00",
                "travelTimeString": "3 min.",
                "travelTimeMinutes": 4,
                "exceedsAvailableTime": true
            }
        ],
        "id": "59ef3b8236e16f1c84787c28",
        "stringId": "59ef3b8236e16f1c84787c28"
    }
}

// Transform data
const travelTimes = data.order.travelTimes.map(item => _.omit(item, ['id']) )
const orderLines = _.merge(data.order.orderLines, travelTimes)
const order = _.omit(data.order, ['orderLines', 'travelTimes'])
const orders = _.assign(order, { orderLines })

const addonGroups = _.groupBy(order.orderLines, 'connectedTo')
const addons = _.omit(addonGroups, 'undefined')
const products = _.pick(addonGroups, 'undefined')
const productGroups = _.groupBy(products.undefined, 'stringId')

console.log(productGroups) // All parent products
console.log(addons) // All addon products

const arr1 = _.values(_.flatMap(productGroups))
const arr2 = _.values(_.flatMap(addons))

Code on Codepen.io

Any help is greatly appreciated!
Let me know if I need to explain in further detail.

Answers:

Not sure if I understood correctly what the expected result is, but I gave it a try anyway.

const orderLines = _(data.order.orderLines)
    .map(item => {
        if (!item.connectedTo) return _.assignIn(item, { addons: [] });

        const match = _.find(data.order.orderLines, { id: item.connectedTo });
        match.addons = match.addons || [];
        match.addons.push(item);

        return null;
    })
    .compact()
    .value();

Check the output here: https://codepen.io/andreiho/pen/YEzQRd?editors=0012