Retrieving data using ngxs selector for displaying nested JSON data

My issue is related to the user object that contains nested arrays, making it difficult to access secondary arrays. I have created selectors with ngxs to retrieve and utilize data in HTML code, but extracting secondary arrays seems impossible.

{
  "userProfile": {
    "id": 1,
    "firstname": "kevin",
    "lastname": "kevin",
    "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="33565e525a5f73545e525a5f1d505c5e">[email protected]</a>",
    "phone": "6949647400",
    "cart": {
      "id": 6,
      "grandTotal": 1000,
      "cartItem": [
        {
          "id": 5,
          "quantity": 1,
          "totalPrice": 55.5,
          "product": {
            "id": 1,
            "name": "Vans Shoes",
            "price": 55.5
          }
        },
        {
          "id": 6,
          "quantity": 1,
          "totalPrice": 111,
          "product": {
            "id": 2,
            "name": "Nike Shoes",
            "price": 55.5
          }
        },
        {
          "id": 7,
          "quantity": 1,
          "totalPrice": 55.5,
          "product": {
            "id": 3,
            "name": "Volcom T-shirt",
            "price": 55.5
          }
        }
      ]
    },
    "username": "kevin",
    "password": "$2a$10$PITUkb3QoOCIbZSDO9xLzOdfKwM.H/sFp.pgYnfssi31LIn8WotW2",
    "roles": [
      {
        "id": 3,
        "name": "ROLE_ADMIN"
      }
    ]
  }
}

The above array is received from a backend call. My goal is to display the cart{} array along with its products in the frontend.

import { Component, OnInit } from '@angular/core';
import { Cart } from 'src/app/core/interfaces/cart';
import { CartState} from './state/cart.state';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { UserProfile } from 'src/app/core/interfaces/userProfile';
import { ProfileState } from 'src/app/pages/profile/state/profile.state';
import { GetCart, } from './state/cart.action';

export class UserProfile {
  id!: number;
  username!: string ;
  password!: string ;
  email!:string;
  firstname!: string ;
  lastname!: string ;
  roles!: Roles;
  token!: string ;
  cart!:Cart[];
}


@Component({
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.css'],
})
export class CartComponent implements OnInit {
  userId! :number;
  cartId! :number;
  cart! :any[];

  @Select(ProfileState.userProfile) userProfile$!: Observable<UserProfile>;
  
  @Select(CartState.cart)cart$!: Observable<Cart>;

  constructor(private store:Store) {}

  ngOnInit(){
    this.userProfile$.subscribe(userProfileData => {
      this.userId = userProfileData.id
     });
      this.store.dispatch(new GetCart(this.userId)).subscribe(response => {
        this.cart = response;
     })
  }
}

Answer №1

Firstly, it is recommended to make your UserProfile class an interface rather than a class.

Secondly, please note that userProfileData.cart is not an array but an object containing properties like id: number, grandTotal: number, and cartItem: SomeCartItem[].

Make sure to properly subscribe to the cart using @Select(CartState.cart) and dispatch actions only when the userId is available. Don't forget to properly unsubscribe() from Observables.

See the example below:

// your-component.ts
public ngOnInit(): void {
  this.userProfile$.subscribe(userProfileData => {
    this.userId = userProfileData.id

    this.store.dispatch(new GetCart(this.userId));
  });

  this.cart$.subscribe(cart => {
    this.cart = cart;
    // you can access cartItems from the cart object here
  });
}

public ngOnDestroy(): void {
  this.userProfile$.unsubscribe();
  this.cart$.unsubscribe();
}

Answer №2

I encountered an issue while working on this HTML code snippet:

<div class="container">
  <div class="row">
    <tbody *ngIf="cart;">
  <div *ngFor="let cartItem of cart">
    <div *ngFor="let product of cartItem.product">
  <ul>
    <li>{{product.name }}</li>
  </ul>
  </div>
  </div>
</tbody>
  </div>
</div>

I'm stuck at this point and would appreciate any guidance or advice. I was considering using material-pagination as it seems like a simpler way to display the data from cartItem rather than using ngfor.

core.js:6456 ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

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

Develop a JSON parsing function for VUE reusability

Currently, I am iterating through an array in Vue that contains objects with strings nested within. These objects have various properties such as idType, type, user, visibility, seller, product, company, and additionalData. notifications: [ 0: { idTy ...

Choosing the Right Language for AngularJS 2: TypeScript, JavaScript, or Dart?

AngularJS 2 is on the horizon, and the documentation recommends three languages: Typescript, Javascript, and Dart. As someone who primarily works with Javascript EcmaScript 5, I'm curious about the strengths and weaknesses of these three options. Cu ...

Encountered difficulties in deploying functions on Firebase Cloud Functions

While developing the Firebase Cloud Functions, I organized the files based on each function. Unfortunately, numerous errors occurred during deployment. Error [debug] [2022-07-19T14:36:17.677Z] <<< [apiv2][body] GET https://us.gcr.io/v2/xxxxxx/gcf ...

The never-ending scroll feature in Vue.js

For the component of cards in my project, I am trying to implement infinite scrolling with 3 cards per row. Upon reaching the end of the page, I intend to make an API call for the next page and display the subsequent set of cards. Below is my implementatio ...

Error encountered while sending a post request from Angular to NodeJS with JSON data

When making a POST request to a NodeJS app from Angular, the request code in Angular is as follows: export class SearchComponent { constructor(private http: HttpClient) {} newWord = ''; keyword = ''; onClick() { const head ...

Tips for testing nested subscribe methods in Angular unit testing

FunctionToTest() { this.someService.method1().subscribe((response) => { if (response.Success) { this.someService.method2().subscribe((res) => { this.anotherService.method3(); }) } }); } Consider the following scenario. ...

Combining two sets of data into one powerful tool: ngx-charts for Angular 2

After successfully creating a component chart using ngx-charts in angular 2 and pulling data from data.ts, I am now looking to reuse the same component to display a second chart with a different data set (data2.ts). Is this even possible? Can someone guide ...

Challenges encountered when implementing a personal library in a separate project

After updating a library I own, I seem to have encountered an issue when trying to use it in another project. However, the reason for this problem eludes me. A multitude of error logs with a similar theme are appearing: ERROR in ./node_modules/@company-na ...

Having trouble with importing and receiving the error message "Module 'clone' not found."

When trying to use clone.js in Angular 2, I imported it with import * as clone from 'clone'. It was listed in my package.json dependencies and successfully imported into node_modules. However, when viewing the output, I encountered the error mes ...

Unable to locate module: Issue: Unable to locate '@angular/cdk/tree' or '@angular/material/tree'

Currently utilizing Angular 5 and attempting to create a tree view that resembles a table layout. https://stackblitz.com/edit/angular-hhkrr1?file=main.ts Encountering errors while trying to import: import {NestedTreeControl} from '@angular/cdk/tree ...

Is there a way to display a variety of images on separate divs using *ngFor or another method?

I have created a custom gallery and now I would like to apply titration on the wrapper in order to display a different image on each div. Currently, my code is repeating a single image throughout the entire gallery. HTML <div class="wrapper" ...

Webpack is struggling to locate core-js paths when running on Windows operating systems

When running webpack, I am encountering the following errors: ERROR in ./node_modules/core-js/index.js Module not found: Error: Can't resolve './es' in 'pathtoproject\node_modules\core-js' @ ./node_modules/core-js/index. ...

Using Angular's routerLink within an element's innerHTML

As I searched for a way to make standard a[href] links act like routerLinks when loaded dynamically into [innerHTML], I realized that this functionality is not provided out of the box. After exploring various options, I was unable to find a solution that m ...

Error: Uncaught TypeError - The function boss.SetBelongToClan is not defined

Currently, I am faced with an issue while working on a typescript and sequelize project within an express application. The problem arises when trying to create a type-safe interface for utilizing the associate function. Within my Instance interface, there ...

Having difficulty subscribing to multiple observables simultaneously using withLatestFrom

I am facing an issue where I have three observables and need to pass their values to a service as parameters. I attempted to do this using WithLatestFrom(), but it works fine only when all values are observables. this.payment$.pipe( withLatestFrom(this.fir ...

Styling in Svelte/TS does not change when applied through a foreach loop

I've been experimenting with creating a unique "bubble" effect on one of my websites, but I'm facing difficulty changing the styling in a foreach loop. Despite no errors showing up in the console, I'm at a loss as to how to effectively debu ...

What is the best way to display two arrays next to each other in an Angular template?

bolded text I am struggling to display two arrays side by side in an angular template. I attempted to use ngFor inside a div and span but the result was not as expected. A=[1,2,3,4] B=[A,B,C,D] Current Outcome using ngFor with div and span : Using Div : ...

Error: This property is not available on either 'false' or 'HTMLAudioElement' types

When working with React (Next.js) using hooks and typescript, I encountered an issue while trying to create a reference to an Audio element. The error message I received was: Property 'duration' does not exist on type 'false | HTMLAudioEleme ...

Combine both typescript and javascript files within a single Angular project

Is it feasible to include both TypeScript and JavaScript files within the same Angular project? I am working on a significant Angular project and considering migrating it to TypeScript without having to rename all files to .ts and address any resulting er ...

In the CallableFunction.call method, the keyword "extends keyof" is transformed into "never"

In the following method, the type of the second parameter (loadingName) is determined by the key of the first parameter. (alias) function withLoading<T, P extends keyof T>(this: T, loadingName: P, before: () => Promise<any>): Promise<void ...