2

I am building an app with node.js, mssql (don't ask.. client), socket.io and angularjs.

I have managed to get data from mssql to angular in the following form.

[
    {
        "measure":"value",
        "region":"London",
        "manager":"Jack",
        "supervisor":"James",
        "number1":44,
        "number2":2244.3,
        "number3":1561.6
    },
    {
        "measure":"value",
        "region":"London",
        "manager":"Jack",
        "supervisor":"Jerry",
        "number1":335.4,
        "number2":33.3,
        "number3":11.6
    },
    {
        "measure":"value",
        "region":"London",
        "manager":"John",
        "supervisor":"Joseph",
        "number1":444.3,
        "number2":233,
        "number3":1561.6
    }
]

I am trying to manipulate the data through angular.forEach to achieve the following result:

[
    {
        "region": "London",
        "regionTotals" : {
            "turnover" : {
                "number1" : "TOTAL OF NUMBER 1 WITH REGION LONDON",
                "number2" : "TOTAL OF NUMBER 2 WITH REGION LONDON",
                "number3" : "TOTAL OF NUMBER 3 WITH REGION LONDON"
            }
        },
        "managers" : {
            "jack" : {
                "managerTotals" {
                    "number1": "TOTAL OF NUMBER 1 WITH MANAGER JACK",
                    "number2": "TOTAL OF NUMBER 2 WITH MANAGER JACK",
                    "number3": "TOTAL OF NUMBER 3 WITH MANAGER JACK"
                },
                "supervisors" : {
                    "Jerry": {
                        "supervisorTotals" : {
                            "number1":335.4,
                            "number2":33.3,
                            "number3":11.6
                        }
                    },
                    "James": {
                        "supervisorTotals" : {
                            "number1":44,
                            "number2":2244.3,
                            "number3":1561.6
                        }
                    }
                }
            },
            "john" : {
                "managerTotals" {
                    "number1": "TOTAL OF NUMBER 1 WITH MANAGER JOHN",
                    "number2": "TOTAL OF NUMBER 2 WITH MANAGER JOHN",
                    "number3": "TOTAL OF NUMBER 3 WITH MANAGER JOHN"
                },
                "supervisors" : {
                    "Joseph": {
                        "supervisorTotals" : {
                            "number1":444.3,
                            "number2":233,
                            "number3":1561.6
                        }
                    }
                }
            }
        }
    }
]

Is this the best way to do this? And if you have any advice on how to run it through a javascript loop it would be much appreciated as I'm struggling big time. Especially trying to set the object keys.

The only other way I can think of doing it is running a bunch of queries in node and putting it together server side rather than client side. However considering I'm using mssql I wanted to keep queries to a bare minimum.

Thanks

6
  • so your question is about data transformation is that correct? i would use something like array.prototype.reduce to transform my arrayinto the object you can learn more about it here developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Jun 24, 2014 at 2:45
  • 2
    Impossible to tell if it's "the best way" given that you haven't posted any code or any criteria for "best" (such as fast, easy to maintain, widely compatible, etc.). forEach is likely a reasonable choice, but may or may not be "best". Commented Jun 24, 2014 at 3:25
  • Thanks for your comments. @DayanMorenoLeon yes data transformation is the basis of the question, I will have a look into the reduce method. Commented Jun 24, 2014 at 3:33
  • @RobG Ease of programming first and application speed second would be the main criteria as this is one of many sets of data I have to do similar manipulation for different views, I assume focusing on one probably results in opposite solutions! Commented Jun 24, 2014 at 3:34
  • 1
    If you totally get how reduce, map, filter work then using them can be great. But many struggle, so plain loops with well chosen variable names may be best for easy understanding and maintenance. And they will likely be faster than nested iterators, sometimes a lot faster as they have far fewer function calls. Commented Jun 24, 2014 at 3:55

1 Answer 1

1

I wont say this is the best solution but rather a solution which achieves your goal

I have flattened the JSON into the corresponding structure by using certain iteration with .reduce and angular.forEach. The $scope.flattenedRecord contains the converted JSON

Working Demo

var app = angular.module('myApp', []);
app.controller('ArrayController', function ($scope) {
    $scope.records = [{
        "measure": "value",
            "region": "London",
            "manager": "Jack",
            "supervisor": "James",
            "number1": 44,
            "number2": 2244.3,
            "number3": 1561.6
    }, {
        "measure": "value",
            "region": "London",
            "manager": "Jack",
            "supervisor": "Jerry",
            "number1": 335.4,
            "number2": 33.3,
            "number3": 11.6
    }, {
        "measure": "value",
            "region": "London",
            "manager": "John",
            "supervisor": "Joseph",
            "number1": 444.3,
            "number2": 233,
            "number3": 1561.6
    }];

    $scope.flattenedRecord = [];

    $scope.managers = [];
    $scope.region = [];

    $scope.records.reduce(function (result, item) {
        $scope.managers.push(item.manager);
        $scope.region.push(item.region);
    }, 0);

    $scope.managers = _.uniq($scope.managers);
    $scope.region = _.uniq($scope.region);

    var mainRecordobj = {};

    angular.forEach($scope.region, function (regionValue) {
        mainRecordobj.region = regionValue;
        var regionTurnoverObj = {};
        var regionNumberObj = {};
        var regionTotalsObj = {};

        var supervisorTotalsObj = {};
        var supervisorNumberObj = {};
        var supervisorNameObj = {};

        var managerTotalsObj = {};
        var managerNameObj = {};
        var managerNumberObj = {};

        regionNumberObj.number1 = "TOTAL OF NUMBER 1 WITH REGION " + regionValue.toUpperCase();
        regionNumberObj.number2 = "TOTAL OF NUMBER 2 WITH REGION " + regionValue.toUpperCase();
        regionNumberObj.number3 = "TOTAL OF NUMBER 3 WITH REGION " + regionValue.toUpperCase();

        angular.forEach($scope.managers, function (managerName) {


            managerNumberObj = {};
            managerNumberObj.number1 = "TOTAL OF NUMBER 1 WITH MANAGER " + managerName.toUpperCase();
            managerNumberObj.number2 = "TOTAL OF NUMBER 2 WITH MANAGER " + managerName.toUpperCase();
            managerNumberObj.number3 = "TOTAL OF NUMBER 3 WITH MANAGER " + managerName.toUpperCase();
            managerTotalsObj = {};

            managerTotalsObj.managerTotals = managerNumberObj;
            supervisorNameObj = {};

            angular.forEach($scope.records, function (recordArray, recordIndex) {

                if (managerName === recordArray.manager) {
                    angular.forEach(recordArray, function (recordValue, recordKey) {

                        if (recordValue === managerName) {
                            supervisorNumberObj = {};
                            supervisorNumberObj.number1 = recordArray.number1;
                            supervisorNumberObj.number2 = recordArray.number2;
                            supervisorNumberObj.number3 = recordArray.number3;
                            supervisorTotalsObj = {};
                            supervisorTotalsObj.supervisorTotals = supervisorNumberObj;
                            supervisorNameObj[recordArray.supervisor] = supervisorTotalsObj;
                        }

                    });
                }
            });

            managerTotalsObj.supervisors = supervisorNameObj;
            managerNameObj[managerName.toLowerCase()] = managerTotalsObj;
        });
        regionTurnoverObj.turnover = regionNumberObj;
        mainRecordobj.regionTotals = regionTurnoverObj;
        mainRecordobj.managers = managerNameObj;
        $scope.flattenedRecord.push(mainRecordobj);
        console.log(angular.toJson($scope.flattenedRecord));
    });
});

OUTPUT

[
  {
    "region": "London",
    "regionTotals": {
      "turnover": {
        "number1": "TOTAL OF NUMBER 1 WITH REGION LONDON",
        "number2": "TOTAL OF NUMBER 2 WITH REGION LONDON",
        "number3": "TOTAL OF NUMBER 3 WITH REGION LONDON"
      }
    },
    "managers": {
      "jack": {
        "managerTotals": {
          "number1": "TOTAL OF NUMBER 1 WITH MANAGER JACK",
          "number2": "TOTAL OF NUMBER 2 WITH MANAGER JACK",
          "number3": "TOTAL OF NUMBER 3 WITH MANAGER JACK"
        },
        "supervisors": {
          "James": {
            "supervisorTotals": {
              "number1": 44,
              "number2": 2244.3,
              "number3": 1561.6
            }
          },
          "Jerry": {
            "supervisorTotals": {
              "number1": 335.4,
              "number2": 33.3,
              "number3": 11.6
            }
          }
        }
      },
      "john": {
        "managerTotals": {
          "number1": "TOTAL OF NUMBER 1 WITH MANAGER JOHN",
          "number2": "TOTAL OF NUMBER 2 WITH MANAGER JOHN",
          "number3": "TOTAL OF NUMBER 3 WITH MANAGER JOHN"
        },
        "supervisors": {
          "Joseph": {
            "supervisorTotals": {
              "number1": 444.3,
              "number2": 233,
              "number3": 1561.6
            }
          }
        }
      }
    }
  }
]
Sign up to request clarification or add additional context in comments.

2 Comments

It doesn't completely solve my problem as I wanted the "TOTAL" values in caps literally added up from the supervisor numbers.. However a big thankyou for putting in the time and it has given me some good ideas!!
Hi James did you received my mail which I have droped in response to your mail on June 26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.