Búsqueda de sitios web

javascript - TypeError: "ctx.cart no está definido"


Estoy trabajando en una aplicación de pedidos de pizza y actualmente estoy intentando implementar el carrito.

Tengo un carrito para cada usuario, y cada carrito contiene los siguientes detalles: cart.ts

import { CartItem } from './cartitem';

export class Cart {
    id: string;
    user: string;
    cartitems: CartItem[];
    grand_total: number;
}

El usuario puede agregar artículos del menú, que se convertirán en los artículos de mi carrito: cartitem.ts

import { Topping } from './topping';
export class CartItem {
    id: string;
    name: string;
    baseprice: number;
    toppings: Topping[];
    extraprice: number;
    quantity= 1;
    total: number;
}

Así que al agregar un artículo al carrito, estoy haciendo una solicitud PUT en el endpoint de la API en el carrito del usuario, para poner el artículo en el carrito, y en respuesta, estoy devolviendo el contenido del carrito desde allí.

Así es como se ve mi cart.component.ts:

import { Component, OnInit, ViewChild, Inject, Injector } from '@angular/core';
import { CartItem } from '../shared/cartitem';
import { ActivatedRoute } from '@angular/router';
import { CartService } from '../services/cart.service';
import { map, catchError } from 'rxjs/operators';
import { Cart } from '../shared/cart';

@Component({
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.scss']
})
export class CartComponent implements OnInit {

  cart: Cart;
  // cartitems: CartItem[];

  constructor(
    private route: ActivatedRoute,
    private cartService: CartService,
    @Inject('BaseURL')public BaseURL) { }


  ngOnInit(): void {
    this.updateCart();

  }

  updateCart() {
    this.cartService.mysubject.subscribe((value) => {
      console.log(value);
      this.cartService.getItems().subscribe(response => {
        console.log("Response in cart comp:", response);

        let cartContent = new Cart();
        cartContent.cartitems = response['cartitems'];
        cartContent.id = response['id'];
        cartContent.grand_total = response['grand_total'];
        cartContent.user = response['user'];

        this.cart = cartContent;

        console.log("Cart is:", this.cart);

      });
    });
  }

}

Ahora el problema aquí es que no puedo enlazar los datos en el lado de cart.component.html con 'cart', genera este error: ERROR TypeError: "ctx.cart es indefinido".

No tengo ni idea de cómo arreglar esto.

Editar: Aquí está el cart.component.html:

<h2>Cart</h2>
<div>{{cart.user}}</div>
<mat-list dense>
    <mat-list-item *ngFor="let cartitem of cart.cartitems">
        <h2 matLine>Item: {{cartitem.name}}</h2>
        <p matLine>Base Price: ${{cartitem.baseprice}}</p>
        <p matLine [hidden]="cartitem.toppings == []">Extra Toppings:
            <mat-list matLine>
                <mat-list-item matLine *ngFor="let topping of cartitem.toppings">
                    <h4 matLine>{{topping.name}} : + ${{topping.rate}}</h4>
                </mat-list-item>
            </mat-list>
        </p>
        <button mat-mini-fab color="primary"><i class="fa fa-minus-circle"></i></button><div></div><button mat-mini-fab color="primary"><i class="fa fa-plus-circle"></i></button>
    </mat-list-item>

</mat-list>

<div [hidden]="!cart.cartitems"><h2>Subtotal: ${{cart.grand_total}}</h2></div>

<div [hidden]="cart.cartitems">
    <p> Your Cart is Empty!</p>
</div>

y registro de errores:

ERROR TypeError: "ctx.cart is undefined"
    CartComponent_Template cart.component.html:2
    Angular 26
        executeTemplate
        refreshView
        refreshComponent
        refreshChildComponents
        refreshView
        refreshComponent
        refreshChildComponents
        refreshView
        refreshDynamicEmbeddedViews
        refreshView
        refreshComponent
        refreshChildComponents
        refreshView
        renderComponentOrTemplate
        tickRootContext
        detectChangesInRootView
        detectChanges
        tick
        next
        invoke
        onInvoke
        invoke
        run
        run
        next
        schedulerFn
    RxJS 5
    Angular 8
core.js:6185:19

Respuesta #1

El HTML agregado muestra el error en la línea 2 del HTML

<div>{{cart.user}}</div>

cart se define como en tu archivo TS

cart: Cart;

El valor interpolado cart.user no está disponible ya que cart en sí está indefinido en el momento de la inicialización. cart se completa más tarde cuando la suscripción se resuelve.

Una solución rápida podría ser envolver esto en un ng-container y usar *ngIf en él.

<ng-container *ngIf="cart">
  <h2...
  ...
  </div>
</ng-container>

Esto no mostrará nada hasta que se resuelva el carrito.

Sin embargo, en términos de mejor calidad de código, reemplaza todas tus interpolaciones con getters en TS

get cartUser() { return (cart && cart.user) ? cart.user : null }

Ahora tu HTML será así

<div>{{cartUser}}</div>

De la misma manera, obtendrás un error para cart.cartitems. Usa este getter

get cartCartitems() { return (cart && cart.cartitems) ? cart.cartitems : [] }

y reemplaza todas las instancias de cart.cartitems con cartCartitems en tu HTML

¡Espero que ayude!

Respuesta #2

Resolví este problema con:

cart: Cart = {} as Cart;

en lugar de:

cart: Cart;

Artículos relacionados