Master the art of handling JSON data within an Angular controller

I've been spending a day attempting to manipulate a JSON in order to display a table, but I can't seem to achieve the desired outcome.

My goal is to showcase statistics in a table for each town. If a town has multiple lines, I want to display a subTotal line as well.

The expected output should look like this:

  • line 1 | PARIS | BUILDING A .....
  • line 2 | PARIS | BUILDING D .....
  • subTotal| PARIS | BUILDINGS .....
  • line 3 | LONDON | BUILDING B .....
  • line 4 | LONDON | BUILDING F .....
  • subTotal| LONDON | BUILDINGS .....
  • line 5 | TOKYO | BUILDING C .....
  • line 6 | CHICAGO| BUILDING E .....
  • TOTAL | ALL | .....

This is the code snippet from my controller:

$scope.rowCollection = [ 
        // JSON data goes here
    ];

    var myArray = [];
    for (var i = 0; i < $scope.rowCollection.length; i++) {
        if (Array.isArray(myArray[$scope.rowCollection[i].town])) {
            myArray[$scope.rowCollection[i].town].push($scope.rowCollection[i]);
        } else {
            myArray[$scope.rowCollection[i].town] = $scope.rowCollection[i];
        }
    }

    $scope.myArray = myArray;
    console.log($scope.myArray);

I'm struggling with understanding why the length of my Array is showing as "0". Even when I try to increment it, it still doesn't work. Is this normal behavior?

Thank you for any assistance you can provide.

For further reference, here is a link to the jsfiddle: https://jsfiddle.net/ohu6dhqy/

Answer №1

const application = angular.module('application', []);

function Controller($scope) {
  $scope.dataCollection = [{
    "id": "1",
    "name": "BUILDING A",
    "city": "PARIS",
    "date": "2015-11-09",
    "stat1": 3,
    "stat2": 115,
    "stat3": 4,
    "stat4": 111
  }, {
    "id": "2",
    "name": "BUILDING B",
    "city": "LONDON",
    "date": "2013-11-09",
    "stat1": 1,
    "stat2": 51,
    "stat3": 1,
    "stat4": 50
  }, {
    "id": "3",
    "name": "BUILDING C",
    "city": "TOKYO",
    "date": "2012-10-21",
    "stat1": 0,
    "stat2": 142,
    "stat3": 0,
    "stat4": 142
  }, {
    "id": "4",
    "name": "BUILDING D",
    "city": "PARIS",
    "date": "2011-02-03",
    "stat1": 0,
    "stat2": 132,
    "stat3": 0,
    "stat4": 132
  }, {
    "id": "5",
    "name": "BUILDING E",
    "city": "CHICAGO",
    "stat1": 0,
    "stat2": 94,
    "stat3": 0,
    "stat4": 94
  }, {
    "id": "6",
    "name": "BUILDING F",
    "city": "LONDON",
    "date": "0000-00-00",
    "stat1": 0,
    "stat2": 86,
    "stat3": 0,
    "stat4": 86
  }];

  var groupedData = {};
  var totalData = {
    "totalStat1": 0,
    "totalStat2": 0,
    "totalStat3": 0,
    "totalStat4": 0,
  };

  $scope.dataCollection.forEach(function(item) {
    groupedData[item.city] = groupedData[item.city] || {};
    groupedData[item.city].array = groupedData[item.city].array || [];
    groupedData[item.city].total = groupedData[item.city].total || {
      "totalStat1": 0,
      "totalStat2": 0,
      "totalStat3": 0,
      "totalStat4": 0,
    };
    groupedData[item.city].array.push(item);
    groupedData[item.city].total.totalStat1 += item.stat1;
    groupedData[item.city].total.totalStat2 += item.stat2;
    groupedData[item.city].total.totalStat3 += item.stat3;
    groupedData[item.city].total.totalStat4 += item.stat4;

    totalData.totalStat1 += item.stat1;
    totalData.totalStat2 += item.stat2;
    totalData.totalStat3 += item.stat3;
    totalData.totalStat4 += item.stat4;
  });
  $scope.groupedData = groupedData;
  $scope.totalData = totalData;

}
table {
  margin: 1rem;
  border-collapse: collapse;
  width: 55%;
}
table,
th,
td {
  border: 1px solid black;
}

.total{
 font-weight:800; 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="application" ng-controller="Controller">
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>City</th>
        <th>Date</th>
        <th>Stat1</th>
        <th>Stat2</th>
        <th>Stat3</th>
        <th>Stat4</th>
      </tr>
    </thead>
    <tbody ng-repeat="(key, value) in groupedData">
      <tr ng-repeat="val in value.array">
        <td>{{val.id}}</td>
        <td>{{val.city}}</td>
        <td>{{val.name}}</td>
        <td>{{val.date}}</td>
        <td>{{val.stat1}}</td>
        <td>{{val.stat2}}</td>
        <td>{{val.stat3}}</td>
        <td>{{val.stat4}}</td>
      </tr>
      <tr class="total">
        <td>TOTAL</td>
        <td>-</td>
        <td>-</td>
        <td>-</td>
        <td>{{value.total.totalStat1}}</td>
        <td>{{value.total.totalStat2}}</td>
        <td>{{value.total.totalStat3}}</td>
        <td>{{value.total.totalStat4}}</td>
      </tr>
    </tbody>
  </table>

  <div>
    Total stat 1 : {{totalData.totalStat1}} -
    Total stat 2 : {{totalData.totalStat2}} -
    Total stat 3 : {{totalData.totalStat3}} -
    Total stat 4 : {{totalData.totalStat4}} -
  </div>
</div>

Answer №2

If you want to efficiently organize and display your data, consider optimizing your code in the following way:

let dataArray = [];
for (let index = 0; index < $scope.rowCollection.length; index++) {
    if (Array.isArray(dataArray[$scope.rowCollection[index].city])) {
        dataArray[$scope.rowCollection[index].city].push($scope.rowCollection[index]);
    } else {
        dataArray[$scope.rowCollection[index].city] = $scope.rowCollection[index];
    }
}

$scope.dataArray = dataArray;

To present your data in a well-structured manner, utilize a table setup like this:

<div ng-controller="MyCtrl">
  <table class="table">
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>City</th>
      <th>Date</th>
      <th>Stat1</th>
      <th>Stat2</th>
      <th>Stat3</th>
      <th>Stat4</th>
    </tr>

    <tr ng-repeat="row in rowCollection">
      <td>{{ row.id }}</td>
      <td>{{ row.name }}</td>
      <td>{{ row.city }}</td>
      <td>{{ row.date }}</td>
      <td>{{ row.stat1 }}</td>
      <td>{{ row.stat2 }}</td>
      <td>{{ row.stat3 }}</td>
      <td>{{ row.stat4 }}</td>
    </tr>
  </table>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Releasing Typescript 2.3 Modules on NPM for Integration with Angular 4

Although there are instructions available in Writing NPM modules in Typescript, they are outdated and there are numerous conflicting answers that may not be suitable for Angular. Additionally, Jason Aden has delivered an informative presentation on youtu ...

Challenges with ColdFusion's floating point calculations

I am encountering an issue with my program where it is not displaying two decimal points properly. For example, when I enter 140.00, it shows as 140.0. Strangely, if I enter 140.15, it displays correctly as 140.15. It seems to consistently drop the zero. B ...

Optimal methods for organizing various perspectives on a one-page website

I am developing an application that incorporates AngularJS and Bootstrap. The current setup involves organizing various views using ng-show, allowing for view changes based on button interactions and the enablement/disabling of ng-show values. Within a si ...

Using JSON data to populate an HTML page

I'm currently working on a project that involves creating a "Twitter" page. The idea is to utilize the JSON file available at to display some of its content. However, I'm facing an issue where my page only shows the table headers and nothing els ...

What is the reason for innerHTML not functioning properly when trying to include HTML?

Apologies for my poor English, but I am determined to solve this issue using HTML code. <body> <div id="booklist"> <?php include("../templates/nav.php"); ?> <div class="hero"> <?php include("../templates/aside.ph ...

My Jquery "animate" is only triggered once instead of on each function call. What could be causing this issue?

I have set my navigation to dock at a specific document height on the top of the viewport, and when it docks, it should display a dropdown animation. $(document).scroll(function(){ var x = $(window).scrollTop(); if(x>=700){ $("header ...

Steps for displaying search results based on state when a button is clicked

My current challenge involves creating a component that displays a list of results upon clicking the "Find" button. However, I am encountering issues with the results state variable not resetting when I utilize setResults([]). In addition, only the most r ...

Checkbox malfunctioning when trying to add values after being checked

I have successfully completed a calculation system project using JavaScript. Everything works well, the calculations are accurate and taxes are included properly. However, I am facing an issue where the tax is not being included when I click on the checkbo ...

Getting console data in AngularJS can be achieved by using the console.log()

This log in the console is functioning correctly. Is there a way to retrieve this information for the HTML? ProductController.js $scope.selectedProduct = function(product) { console.log(product.post_title); console.log(product.ID); console.l ...

Tips for separating these two words onto two separate lines

I created this box using Angular Material, but I am having trouble breaking the words "1349" and "New Feedback" into two lines. Here's an image included in my design. Any tips on accomplishing this in Angular Material? Thank you! <style> . ...

What is the most straightforward AngularJs 'Hello World' example you would use when introducing AngularJs to a newcomer?

Can someone provide a beginner-friendly 'Hello World' example in AngularJS? I'm trying to learn and so far have come up with this: <!DOCTYPE html> <html> <head> </head> <body> <div data-ng-app=""> ...

Decoding JSON Array Data Sent via Ajax请求

Could someone provide guidance on parsing this Ajax response in jQuery? {"d":{"__type":"ListUsers+returnData","Type":"Success","Message":"User Added successfully."}} I am utilizing identical return types for various return data scenarios. ...

Discovering the true nature of a generic Type in TypeScript

Consider this scenario involving TypeScript interface IApiCall<TResponse> { method: string; url: string; } Above interface is utilized in the following method; const call = <TResponse>(api: IApiCall<TResponse>): void => { ...

Forwarding HTTP POST requests containing JSON data

We are facing some CORS issues and have decided to implement server proxying as a workaround. However, we are encountering major difficulties with POST requests in this setup. The structure of the proxy is as follows: JQuery-based client -> WebServer H ...

Adding Material-UI icons dynamically in a React TypeScript project requires understanding the integration of imported icons

I have a collection of menu buttons with icons, stored in an array of objects. The icon names are saved as strings that correspond to Material UI icons: interface MenuButton { text: string, onClickFunction: Function icon: string } export defau ...

Guidelines for utilizing a loader to handle a TypeScript-based npm module

I am currently facing a challenge with my React and JavaScript project as I attempt to integrate an npm module developed with TypeScript. The issue lies in configuring my project to compile the TypeScript code from this module, resulting in the error messa ...

ng-hide and ng-switch slow down content visibility

I am implementing a feature to display and hide a clear button based on whether the searchQuery is empty or not. The issue I am facing is that there is a noticeable delay in removing the clear button after the user either clicks it or deletes all input. I ...

Modify the main element of a component

Vue.js requires only a single root element for each component, which is typically wrapped in a div tag. However, this can lead to unexpected issues, such as breaking the layout when using Bootstrap and inserting a div between specific elements like <b-r ...

Utilizing curl to interact with an associative JSON array

I have an array that I need to send: $nums = [ [ 'title' => 'How to build a basic module', 'summary' => 'The summary', 'description' => ...

Within a single component, there are various types present when looping through an array containing objects

Hey there, I'm looking to iterate through an array containing objects with different types within a single component. operations = [ { "id": 15525205, "type": "mise_en_prep", & ...