How to map the nested api json response with a model?

87 Views Asked by At

I am using the model adapter pattern in angular application. How to map this nested json api response to a model in angular?`

[
    {
        "2023": {
            "stock_market": {
                "January": {
                    "invested": "337",
                    "earned": "332.8"
                },
                "February": {
                    "invested": "306",
                    "earned": "299.4"
                },
                "March": {
                    "invested": "334",
                    "earned": "332.0"
                },
                "April": {
                    "invested": "324",
                    "earned": "319.7"
                }
            }
        }
    },
    {
        "2024": {
            "stock_market": {
                "January": {
                    "invested": "337",
                    "earned": "332.8"
                },
                "February": {
                    "invested": "306",
                    "earned": "299.4"
                },
                "March": {
                    "invested": "334",
                    "earned": "332.0"
                },
                "April": {
                    "invested": "324",
                    "earned": "319.7"
                }
            }
        }
    }
]

I have tried to flattened the object. But not fully understanding how to approach this. also how to modify this above json and use adapter with this below format in angular?

{
  totalInvested: '2334',
  returnPercentage: '4.4%',
  description: 'from last year',
  interpretation: 'good returns',
  title: 'Total profit or loss',
}
1

There are 1 best solutions below

6
Manoj Prasanna On BEST ANSWER

you can create TypeScript Interface to represent the data model and then map the nested API JSON response to instances of those classes

 // inteface class
export interface MonthlyData {
  invested: string;
  earned: string;
}

export interface StockData {
  [year: string]: {
    stock_market: {
      [month: string]: MonthlyData;
    };
  };
}

Next, in your Service, import the interfaces and handle the API response:

  // data.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { StockData } from './app.model';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private apiUrl = 'YOUR_API_ENDPOINT'; // Replace with the actual API endpoint URL

  constructor(private http: HttpClient) {}

  getStockData(): Observable<StockData[]> {
    return this.http.get<any[]>(this.apiUrl).pipe(
      map(response => this.mapToStockData(response))
    );
  }

  private mapToStockData(response: any[]): StockData[] {
    // Mapping logic to convert the API response to StockData[]
    const stockDataList: StockData[] = [];
    for (const data of response) {
      for (const year in data) {
        if (data.hasOwnProperty(year)) {
          stockDataList.push({
            [year]: data[year].stock_market
          });
        }
      }
    }
    return stockDataList;
  }
}

finally use the service in your component to fetch the data and map it to the method

    // app.component.ts
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
import { StockData } from './app.model';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  stockDataList: StockData[] = [];

  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    this.fetchDataFromApi();
  }

  fetchDataFromApi(): void {
    this.dataService.getStockData().subscribe(
      (data: StockData[]) => {
        this.stockDataList = data;
        // Now the API response is mapped to the stockDataList array, and you can use it as needed.
      },
      (error) => {
        console.error('Error fetching data:', error);
      }
    );
  }
}

You can follow this example aswell Try it out

I hope it will help you thank you :D