Developing a dynamic object in Typescript to structure and optimize API responses

Currently Working Explanation:

This is similar to the data array received from the API response

responseBarDataStacked = [
    { sku: "Data 1", month: "Jun", value: 20 },
    { sku: "Data 2", month: "Jun", value: 25 },
    { sku: "Data 3", month: "Jun", value: 35 },
    { sku: "Data 4", month: "Jun", value: 10 },
    { sku: "Data 5", month: "Jun", value: 10 },
    { sku: "Data 1", month: "Jul", value: 20 },
    { sku: "Data 2", month: "Jul", value: 30 },
    { sku: "Data 3", month: "Jul", value: 15 },
    { sku: "Data 4", month: "Jul", value: 20 },
    { sku: "Data 5", month: "Jul", value: null },
    { sku: "Data 1", month: "Aug", value: 20 },
    { sku: "Data 2", month: "Aug", value: 30 },
    { sku: "Data 3", month: "Aug", value: 15 },
    { sku: "Data 4", month: "Aug", value: 20 },
    { sku: "Data 5", month: "Aug", value: 15 },
];

Please Note: This depiction of data does not guarantee consistency in the number of SKU sets or months. However, it assures that neither SKU nor month will be null.

I am endeavoring to utilize this response data with Charts (ng2-chart) for the creation of Stacked Bar Graphs. In order for this data to function effectively on the Stacked Bar Chart, I needed to format it logically to obtain the final data as follows,

{
  data: [20, 25, 35, 10, 10], label: 'Jun', stack: 'sameStack',
  data: [20, 30, 15, 20, null], label: 'Jul', stack: 'sameStack',
  data: [20, 30, 15, 20, 15], label: 'Aug', stack: 'sameStack',
}

The arrangement of the data array is structured in the following sequence

data: [valueof[Data 1] for month Jun, valueof[Data 2] for month Jun, valueof[Data 3] for month Jun, valueof[Data 3] for month Jun, valueof[Data 5] for month Jun]

and so forth for others.

Why this specific order?? Because uniqueSku is set in FCFS method below formatStackedBarData() i.e.

["Data 1", "Data 2", "Data 3", "Data 4", "Data 5"]

This is the methodology adopted to align the data accordingly.

  formatStackedBarData(dataToFormat: Array<any>) {
    let uniqueMonth = [...new Set(dataToFormat.map(item => item.month))];
    let uniqueSku = [...new Set(dataToFormat.map(item => item.sku))];
    let stackedBarChartData = [];

    uniqueMonth.forEach(month => {
      let uniqueMonthData = dataToFormat
        .filter(barStackData => barStackData.month == month)
        .map(uniqueStackData => uniqueStackData.value);
      stackedBarChartData.push({
        data: uniqueMonthData,
        label: month,
        stack: 'sameStack'
      });
    });

    return {
      stackedBarChartData,
      uniqueSku
    };
  }

Query:

If the response gets disorganized or if the order of sku changes, I encounter difficulties obtaining appropriate data on the stackedBarChartData.

Now, the response data has been altered as shown below

  responseBarDataStacked = [
    { sku: 'Data 1', month: 'Jun', value: 20 },
    { sku: 'Data 2', month: 'Jun', value: 25 },
    { sku: 'Data 3', month: 'Jun', value: 35 },
    { sku: 'Data 5', month: 'Jun', value: 10 },
    { sku: 'Data 1', month: 'Jul', value: 20 },
    { sku: 'Data 2', month: 'Jul', value: 30 },
    { sku: 'Data 1', month: 'Aug', value: 20 },
    { sku: 'Data 2', month: 'Aug', value: 30 },
    { sku: 'Data 3', month: 'Aug', value: 15 },
    { sku: 'Data 4', month: 'Aug', value: 20 },
    { sku: 'Data 5', month: 'Aug', value: 15 }
  ];

As observed

  • Data 4 is missing for the month of Jun
  • Data 3, Data 4, and Data 5 are absent for the month of Jul

In such scenarios, the anticipated value for stackedBarChartData would resemble the following

[
  {data:[20, 25, 35, 10, null], label: 'Jun', stack: 'sameStack'},
  {data:[20, 30, null, null, null], label: 'Jun', stack: 'sameStack'},
  {data:[20, 30, 15, 15, 20], label: 'Jun', stack: 'sameStack'},
]

Note: In the first object's data, the last value is null due to the order determined by uniqueSku, where Data 5 precedes Data 4 in our API Response.

["Data 1", "Data 2", "Data 3", "Data 5", "Data 4"]

To facilitate understanding, a test implementation has been showcased here. stackblitz implementation

Answer №1

To gather a list of distinct sku, utilize the array#map function along with Set. Subsequently, construct an order object linking each sku with its index to facilitate value assignment for a particular sku.

Following this, employ array#reduce to group the data by month and assign values to the data based on the respective sku entries.

const dataList = [ { sku: 'Data 1', month: 'Jun', value: 20 }, { sku: 'Data 2', month: 'Jun', value: 25 }, { sku: 'Data 3', month: 'Jun', value: 35 }, { sku: 'Data 5', month: 'Jun', value: 10 }, { sku: 'Data 1', month: 'Jul', value: 20 }, { sku: 'Data 2', month: 'Jul', value: 30 }, { sku: 'Data 1', month: 'Aug', value: 20 }, { sku: 'Data 2', month: 'Aug', value: 30 }, { sku: 'Data 3', month: 'Aug', value: 15 }, { sku: 'Data 4', month: 'Aug', value: 20 }, { sku: 'Data 5', month: 'Aug', value: 15 } ],
      uniqueSkuList = [...new Set(dataList.map(item => item.sku))],
      orderData = Object.fromEntries(uniqueSkuList.map((v,i) => ([v, i]))),
      outputResult = Object.values(dataList.reduce((r, {month, value, sku}) => {
        r[month] ||= {data: Array(uniqueSkuList.length).fill(null), label: month, stack: 'sameStack'};
        r[month].data[orderData[sku]] = value;
        return r;
      },{}));
console.log(outputResult);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

Encountering a Pulumi problem during infrastructure packaging: Unable to utilize an import statement beyond a module

I am experimenting with a new approach in Pulumi: bundling the infrastructure. My approach involves deploying a simple S3 bucket by leveraging an npm package. Here is the content of my bucket npm package: index.ts import * as aws from "@pulumi/aws&q ...

The File Filter feature of Angular's ng2-file-upload is not functioning correctly for PNG files in the Internet Explorer

I am encountering an issue with the file uploader plugin ng2-file-upload when trying to upload a PNG file using Internet Explorer 11. For some reason, the PNG files are not being added to the queue, even though all other allowed file types work perfectly f ...

What is the reason behind hidden DOM elements appearing when I refresh the page?

When I refresh my webpage, I notice that the DOM elements I have hidden using ngIf are briefly visible before the actual state of my webpage loads. Why might this be happening? I am currently using Angular 8 version. <div *ngIf="!callInProgress ...

The Next.js build encountered an error - unable to locate function in next/script module

While constructing a CMS using next.js, one of the key components is media management through Cloudinary. The integration of the Cloudinary Media Library widget was successful during development using next/script. However, an error has now emerged that pre ...

Strategies for handling nested arrays within a Vuex Store and seamlessly passing them through components

Within my Vuex Store, there is a state dedicated to planning out the week. planning : [ { name : 'monday', meetings : [ { name : 'morning', value : ...

Breaking up a word string using a comma delimiter in PHP

In one of my recipe ingredient groups, I need to divide a string of text with a comma when notes are specified for any given ingredient. For example - instead of displaying "1 onion red", I want it to display "1 onion, red". Despite trying to use implode, ...

Angular-12 ngx-datatable does not recognize the element 'ngx-caption' in Angular

Within my Angular-12 project, I have set up two modules: AppModule and AdminModule. Specifically, I am utilizing the following module for datatable functionality: "@swimlane/ngx-datatable": "^19.0.0", Here is how it is implemented in ...

Transferring data to a different module

I'm currently working on an Angular program where I am taking a user's input of a zip code and sending it to a function that then calls an API to convert it into latitude and longitude coordinates. Here is a snippet of the code: home.component.h ...

Combining arrays with identical values into a new array?

I have a large array with multiple similar values, but I want to group all arrays with the same value into another array. Here's an example of the array: array(4) { [0]=> array(8) { ["symbol"]=> string(3) "aaaa" ["name"]=> ...

The minimum and maximum validation functions are triggered when I am not utilizing array controls, but they do not seem to work when I use array controls

Take a look at the stack blitz example where min and max validation is triggered: https://stackblitz.com/edit/angular-mat-form-field-icrmfw However, in the following stack blitz with an array of the same controls, the validation does not seem to be worki ...

Working with Angular 4: Utilizing HttpResponse in a Component

I am attempting to retrieve the response from my POST request using Angular 4. Below is the code I am using: app.component.html: `findAccordiSmall(pagination: Pagination) { this.accordiListTableLoading = true; debugger; this.ac ...

Using an array in Android to add a date

I have a list filled with the "ID" values from a database table. To achieve my goal, I need to set specific dates on a calendar based on each ID position. For example, at position 0, I want to set the date as today's date; at position 1, the date shou ...

Having trouble importing the Renderer2 component in Angular

Trying to include Renderer2 with the following import: import { Renderer2 } from '@angular/core'; Encountering an error: "Module 'project/node_modules/@angular/core/index' does not have an exported member 'Renderer2'. Puzz ...

Creating an array of objects data is a breeze with Vue.js

I have an array of data containing selected items, and I need to extract the IDs from this array into a new array so that I can send only the IDs to the back-end. Sample Code method toggleSelection(rows) { console.log('this.multipleSelection : &a ...

Optimizing Your Approach for Rolling Out Test and Development Application Versions on Google Compute Platform

Google Computing Platform I currently have an Angular (2) application and a Node.js middleware (Loopback) running as Services in an App Engine within my project. We are using a Compute Engine to run PostgreSQL for our database in the same project. Our Go ...

Struggling to update a Knockout observable array

I'm attempting to send some data to a Knockout observable array. Despite receiving data from my AJAX call without any errors during script execution, I find that the userNames array remains empty when accessed. What could be causing this issue? UserH ...

Ways to display the ping of a game server on your screen

Is there a way to display the game server's ping on the screen like in the example below? this.tfEnter.text = ShowPing + " ms"; Sometimes the code snippets provided in examples may not function properly. Channel List Image: https://i.stack ...

Executing Timers in Angular 5 Service

I am working on implementing a property called currentAndLastVehicles in my service that needs to be updated automatically every second. Here is what I have so far: import { Injectable } from '@angular/core'; @Injectable() export class SharedD ...

Submit a Post request with a file and JSON information included

I'm encountering an issue while trying to pass files with a JSON object. It seems like there might be an error in the controller where the 'consumes' and 'produces' declarations are possibly incorrect. I need assistance on how to a ...

The TypeError occurs when attempting to access the 'modelReplicationStartDate' property of an undefined entity

Encountering an issue while running Angular unit tests with Jasmine/Karma, resulting in the error message below: TypeError: Cannot read property 'modelReplicationStartDate' of undefined error properties: Object({ longStack: 'TypeError: Canno ...