runnerpaul
runnerpaul

Reputation: 7236

Update json to show count of objects in json array rather than list in Node application

I have this json structure:

    {
        "sales_rep": {
            "1": {
                "id": 1,
                "name": "Joe",
                "email": "[email protected]",
                "customers": [
                    {
                        "id": 1,
                        "address": "1 High Street",
                        "name": "CUSTOMER1",
                        "supplierId": 1,
                    },
                    {
                        "id": 2,
                        "address": "2 High Street",
                        "name": "CUSTOMER2",
                        "supplierId": 1,
                    },
                    {
                        "id": 3,
                        "address": "3 High Street",
                        "name": "CUSTOMER3",
                        "supplierId": 1
                    },
                ]
            }
        }
    }

Is it possible to write a function which will give a count of customers instead of the customer detail? I'm looking to end up with something like this:

    {
        "sales_rep": {
            "1": {
                "id": 1,
                "name": "Joe",
                "email": "[email protected]",
                "customers": "3"
            }
        }
    }

I think I need some sort of reduce function but I'm not sure how to do it.

One of the main problems I'm having is that the original json was generated with this Sequelize model:

let users = db.SalesRep.findAll({
  attributes: ['id', 'name', 'email'],
  include: [{
    model: db.Customers,
    as: 'customers',
  }],
  where: {'id': "1"},
  order: orderClause,
  offset,
  limit,
});

If I add console.log(users) I get this:

Promise {
  _bitField: 0,
  _fulfillmentHandler0: undefined,
  _rejectionHandler0: undefined,
  _promise0: undefined,
  _receiver0: undefined,
  _trace:
   { Error
       at Promise.longStackTracesCaptureStackTrace [as _captureStackTrace] (/Users/paulcarron/git/Eighty8/updated-api/node_modules/bluebird/js/release/debuggability.js:411:19)
       at Promise._then (/Users/paulcarron/git/Eighty8/updated-api/node_modules/bluebird/js/release/promise.js:232:17)
       at Promise.then (/Users/paulcarron/git/Eighty8/updated-api/node_modules/bluebird/js/release/promise.js:125:17)
       at Function.findAll (/Users/paulcarron/git/Eighty8/updated-api/node_modules/sequelize/lib/model.js:1748:8)
       at Function.User.listForAdmin (/Users/paulcarron/git/Eighty8/updated-api/app/models/User.js:65:25)
       at router.get (/Users/paulcarron/git/Eighty8/updated-api/app/controllers/admin.js:277:35)
       at Layer.handle [as handle_request] (/Users/paulcarron/git/Eighty8/updated-api/node_modules/express/lib/router/layer.js:95:5)
       at next (/Users/paulcarron/git/Eighty8/updated-api/node_modules/express/lib/router/route.js:137:13)
       at /Users/paulcarron/git/Eighty8/updated-api/app/middlewares/role.js:6:12
       at Layer.handle [as handle_request] (/Users/paulcarron/git/Eighty8/updated-api/node_modules/express/lib/router/layer.js:95:5)
       at next (/Users/paulcarron/git/Eighty8/updated-api/node_modules/express/lib/router/route.js:137:13)
       at cognitoExpress.validate (/Users/paulcarron/git/Eighty8/updated-api/app/middlewares/access.js:25:7) _parent: undefined, _promisesCreated: 0, _length: 1 } }

Upvotes: 0

Views: 323

Answers (2)

Pushpendra Kumar
Pushpendra Kumar

Reputation: 1684

   let data = {
        "sales_rep": {
            "1": {
                "id": 1,
                "name": "Joe",
                "email": "[email protected]",
                "customers": [
                    {
                        "id": 1,
                        "address": "1 High Street",
                        "name": "CUSTOMER1",
                        "supplierId": 1,
                    },
                    {
                        "id": 2,
                        "address": "2 High Street",
                        "name": "CUSTOMER2",
                        "supplierId": 1,
                    },
                    {
                        "id": 3,
                        "address": "3 High Street",
                        "name": "CUSTOMER3",
                        "supplierId": 1
                    },
                ]
            }
        }
    }

let customerCount = data.sales_rep['1'].customers.length
Object.assign(data.sales_rep['1'], { customers: customerCount})
console.log(data)

db.SalesRep.findAll method is returing promise so you can use await to get the result

   let users = await db.SalesRep.findAll({
      attributes: ['id', 'name', 'email'],
      include: [{
        model: db.Customers,
        as: 'customers',
      }],
      where: {'id': "1"},
      order: orderClause,
      offset,
      limit,
    })
        let sales_rep = users.sales_rep;
        for (let key in sales_rep) {
            sales_rep[key].customers = sales_rep[key].customers.length;
        }

Upvotes: 0

Barmar
Barmar

Reputation: 782107

findAll() is an asynchronous function, it returns a Promise. You need to use .then() to get the result and perform the transformation there.

db.SalesRep.findAll({
  attributes: ['id', 'name', 'email'],
  include: [{
    model: db.Customers,
    as: 'customers',
  }],
  where: {'id': "1"},
  order: orderClause,
  offset,
  limit,
}).then(function(users) {
    let sales_rep = users.sales_rep;
    for (let key in sales_rep) {
        sales_rep[key].customers = sales_rep[key].customers.length;
    }
    // do more stuff with users
});

Upvotes: 2

Related Questions