Search code examples
javascriptarraysnode.jsangularjsdynamic-arrays

Convert raw javascript object array into structured object tree ready for ng-repeat


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


Solution

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