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 } }

2 Answers

2
Barmar On Best Solutions

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
});
0
Pushpendra Kumar On
   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;
        }