Creating Angular models for complex nested JSON structures

I'm a beginner with Angular and I'm dealing with nested API responses from a Strapi application. I've set up a model using interfaces, but I'm having trouble accessing attributes from the product model when trying to access product data.

  "data": [
    {
      "id": 1,
      "attributes": {
        "name": "Banana",
        "description": "Banana",
        "price": 150,
        "status": true,
        "sort_order": 1,
        "slug": null,
        "image": {
          "data": {
            "id": 20,
            "attributes": {
              "name": "product-2.jpg",
              "alternativeText": "product-2.jpg",
              "caption": "product-2.jpg",
              "url": "/uploads/product_2_aeb868f7e6.jpg"
            }
          }
        },
        "categories": {
          "data": [
            {
              "id": 3,
              "attributes": {
                "name": "Fresh Fruits",
                "status": true,
                "sort_order": 3,
                "slug": "fresh-fruits"
              }
            }
          ]
        }
      }
    }
  ],
  "meta": {
    "pagination": {
      "page": 1,
      "pageSize": 3,
      "pageCount": 4,
      "total": 12
    }
  }
}

My Product Model. (product.model.ts)

export class Product {
  data: ProductData[]
  meta: Meta
}

export interface ProductData {
  id: number
  attributes: ProductAttributes
}

export interface ProductAttributes {
  name: string
  description: string
  price: number
  status: boolean
  sort_order: number
  slug: any
  image: ProductImage
  categories: Categories
}

export interface ProductImage {
  data: ImageData
}

export interface ImageData {
  id: number
  attributes: ImageAttributes
}

export interface ImageAttributes {
  name: string
  alternativeText: string
  caption: string
  url: string
}

export interface Categories {
  data: CategoryData[]
}

export interface CategoryData {
  id: number
  attributes: CategoryAttributes
}

export interface CategoryAttributes {
  name: string
  status: boolean
  sort_order: number
  slug: string
}

export interface Meta {
  pagination: Pagination
}

export interface Pagination {
  page: number
  pageSize: number
  pageCount: number
  total: number
}

My Product Service.(product.service.ts)

getProducts(page:Number=1,pageSize:Number=3): Observable<Product[]> {
    return this.http
      .get<Product[]>(
        `${environment.baseUrl}products?populate=*&pagination[pageSize]=${pageSize}&pagination[page]=${page}`
      )
      .pipe(map(resp => resp));
  }

My Product Component.

retrieveProducts(): void {
    this.productService.getProducts(this.page,this.pageSize)
      .subscribe({
        next: (response) => {
          this.products=response.data;(Property 'data' does not exist on type 'Product[]'.)
          console.log(this.products);
        },
        error: (e) => console.error(e)
      });
  }

When attempting to access response.data or response.data.id, I encounter the error 'Property 'data' does not exist on type 'Product[]'. Am I missing something here?

Answer №1

After using online JSON to TypeScript converters, I was able to create improved interfaces for better data handling. Now you can easily access this.products?.data in your code.

products: Products;

retrieveProducts(): void {
    this.productService.getProducts(this.page, this.pageSize)
      .subscribe({
        next: (response) => {
          if (response?.data.length > 0) {
             this.products = response;
             console.log(this.products);
          }
        },
        error: (e) => console.error(e)
      });
  }
 export interface Products {
  data?: (DataEntity)[] | null;
  meta: Meta;
}

// Other Interfaces definitions...

export interface Pagination {
  page: number;
  pageSize: number;
  pageCount: number;
  total: number;
}

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

typescript set parameter conditionally within a function

For my upcoming app, I am working on an API that will utilize Firebase FCM Admin to send messages. Below is the code snippet: import type { NextApiRequest, NextApiResponse } from "next"; import { getMessaging } from "firebase-admin/messaging ...

Can you confirm if npm is successfully connecting through a proxy from Visual Studio 2015?

My first attempt at building an Angular site is hitting a roadblock – I can't seem to restore the json packages using NPM. It looks like there's a proxy issue since I'm behind a corporate firewall. Now, I'm trying to troubleshoot and ...

Error message displayed indicating script not found after executing yarn tsc within a Docker container

Using docker, I successfully built my project by running yarn tsc. However, when I executed docker run -p88:5011 accounts2 I encountered the following error: PM2 error: Error: Script not found: /home/accounts/dist/server/index.js. This error occurs despit ...

The value of the signedIn variable in AWS Amplify is currently undefined

While utilizing the aws-amplify library from the provided website, I observed that the variable this.signedIn is not referenced anywhere on the linked page. My intention is to use it as a boolean indicator, determining whether the user is currently signed ...

Using Typescript to create a generic return type that is determined by the type of a property within an object union

Consider the following scenario: type Setting = { key: "option_one", value: number, } | { key: "option_two", value: string, } export type SettingKey = Setting["key"]; // "option_one"|"option_two ...

"What is the best way to determine the data type of an object retrieved from an API in TypeScript

Hey there, I'm currently developing a web application using Angular 2 and I'm focusing on implementing an exception handling mechanism. To achieve this, I've created a model that mirrors the object structure I will receive from the server (E ...

Tips for cycling through the backend API map reaction in Angular or Typescript

When I make a call to an API, it returns a response in the form of a map: {thomas: 3, test70: 2, tim: 2, elin: 2, sumeet12: 1} I tried iterating over this response in Angular, but encountered an error. Error Encountered: This expression is not callab ...

What is the method by which the Angular compiler handles instances of multiple template reference variables sharing the same name

I am eager to start contributing to Angular and have a unique idea for a feature. My proposal is to enhance the template compiler so that it issues a warning if a template contains two variables with identical names. I believe I am on the right track by ...

Attempting to deploy an Angular 9 web project within Visual Studio

Starting my first Angular project has been a smooth process so far. After successfully running "npm start" without any errors, I encountered some issues when launching the application from Visual Studio. Despite sending the same commands, I consistently ...

Fetching JSON data using Promise.all results in an empty response

I'm facing an issue in my code where I am trying to fetch data from two different JSON files and then return them as arrays. Even after implementing the solution below, it doesn't seem to be working as expected. Can someone guide me on how I can ...

Exploring the world of Angular's HttpClient Requests and Responses

As I delve into the world of signals, I find myself immersed in tutorials and articles on the topic. When it comes to calling an API endpoint using httpClient, I have come across two main approaches that caught my interest. Surprisingly, there isn't m ...

Node-express can seamlessly switch between multiple databases dynamically

After extensive searching for a solution to my problem, I have come up empty-handed. If anyone has experience in similar situations, your help would be greatly appreciated. I have developed an application server in Node Express with MySQL as the database. ...

Unable to locate the JSON file

As I work with a JSON file named email_templates.json in conjunction with my bootstrap.js file, located in the same folder, I encountered an error when attempting to read the file. Error: no such file or directory, open './email_templates.json' ...

Heroku Express API encountering JWT Error: Secret or Private Key is Missing

I recently deployed my API to Heroku, but I encountered some errors when trying to login. Below is a snippet of my code - const express = require("express"); const app = express(); const mongoose = require("mongoose"); const dotenv = r ...

React-snap causing trouble with Firebase

I'm having trouble loading items from firebase on my homepage and I keep running into an error. Does anyone have any advice on how to fix this? I've been following the instructions on https://github.com/stereobooster/react-snap and here is how ...

Issue: Unable to link to 'FormGroup' because it is not recognized as a valid property of 'form'

app.module.ts import { BrowserModule } from '@angular/platform-browser'; import {CUSTOM_ELEMENTS_SCHEMA, NgModule} from '@angular/core'; import {RouterModule} from '@angular/router'; import {AppRoutes} from './app.routin ...

Error Message: "Encountered an Issue with Angular Dynamic

I am currently experimenting with a small reference application to explore the concept of dynamically injecting components into another component in order to display content on a page. Recently, I encountered an error related to the ViewContainerRef object ...

Issues encountered when retrieving data with ReactiveForms

My current project involves gathering data using ReactiveForms. Here is the structure of my setup: Initially, I create a modal to gather the necessary data: async present(){ const modal = await this.modalController.create({ component: dataComponent, cs ...

There is no imageURL property available for this type

Everything was running smoothly on my local project, but encountered errors upon deploying to Vercel: The properties imageURL and alt do not exist on type {} Despite attempting to define the types based on suggestions from Stack Overflow, the issues per ...

Guidance on incorporating a function as a prop in React using TypeScript

I'm currently learning TypeScript with React and ran into an issue. I attempted to pass a function as a property from my App component to a child component named DataForm. However, I encountered the following error: Type '(f: any) => any&ap ...