Home > Mobile >  Angular PrimeNG tag component value cannot bind object
Angular PrimeNG tag component value cannot bind object

Time:06-06

When I navigate to order page got values of all fields except in <p-tag field...Blank field is showing and getting following errors

Cannot read properties of undefined (reading 'label')

I am using angular version 13

All codes are given below

orders-list.component.html

          <ng-template pTemplate="header">
            <tr>
              <th pSortableColumn="dateOrdered">
                Date Ordered <p-sortIcon field="dateOrdered"></p-sortIcon>
              </th>
              <th pSortableColumn="status">Status <p-sortIcon field="status"></p-sortIcon></th>
              <th></th>
            </tr>
          </ng-template>
          <ng-template pTemplate="body" let-order>
            <tr>
              <td>{{ order.dateOrdered | date: 'short' }}</td>
              <td>
                <p-tag
                  [value]="orderStatus[order.status].label"
                  [severity]="orderStatus[order.status].color"
                ></p-tag>
              </td>
            </tr>
          </ng-template>

orders-list.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Order, OrdersService } from '@bluebits/orders';
import { ORDER_STATUS } from '../order.constants';

@Component({
  selector: 'admin-orders-list',
  templateUrl: './orders-list.component.html',
  styles: []
})
export class OrdersListComponent implements OnInit {
  orders: Order[] = [];
  orderStatus = ORDER_STATUS;
  constructor(
    private ordersService: OrdersService,
    private router: Router
  ) {}

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

  _getOrders() {
    this.ordersService.getOrders().subscribe((orders) => {
      this.orders = orders;
    });
  }
}

orders.constants.ts

export const ORDER_STATUS = {
  0: {
    label: 'Pending',
    color: 'primary'
  },
  1: {
    label: 'Processed',
    color: 'warning'
  },
  2: {
    label: 'Shipped',
    color: 'warning'
  },
  3: {
    label: 'Delivered',
    color: 'success'
  },
  4: {
    label: 'Failed',
    color: 'danger'
  }
};

orders.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Order } from '../models/order';
import { environment } from '@env/environment';

@Injectable({
  providedIn: 'root'
})
export class OrdersService {
  apiURLOrders = environment.apiUrl   'orders';

  constructor(private http: HttpClient) {}

  getOrders(): Observable<Order[]> {
    return this.http.get<Order[]>(this.apiURLOrders);
  }
}

CodePudding user response:

You are getting status as string value in you response you should change your mapping Object to use label as key property

export const ORDER_STATUS = {
  'Pending': {
    label: 'Pending',
    color: 'primary'
  },
  'Processed': {
    label: 'Processed',
    color: 'warning'
  },
  'Shipped': {
    label: 'Shipped',
    color: 'warning'
  },
  'Delivered': {
    label: 'Delivered',
    color: 'success'
  },
  'Failed': {
    label: 'Failed',
    color: 'danger'
  }
};

CodePudding user response:

The value provided for status in your orders' data doesn't match with the key of ORDER_STATUS.

@Chellappan's answer is the easiest and quickest to solve the issue.

Or you have to convert the key-value pair for ORDER_STATUS to an array. Next query the array with the order.status to find the ORDER_STATUS' index.

  1. Convert ORDER_STATUS from key-value pair to array with dictionary's value.
ngOnInit(): void {
  this._getOrders();

  this.getOrderStatusList();
}

getOrderStatusList() {
  Object.keys(this.orderStatus).forEach((x) =>
    this.orderStatusList.push(this.orderStatus[x])
  );
}
  1. Query orderStatusList by label to get the first element of matched status.
getOrderStatus(status: string) {
  let orderStatus = this.orderStatusList.find((x) => x.label == status);

  return orderStatus;
}

For HTML:

Either

<p-tag
  [value]="getOrderStatus(order.status).status"
  [severity]="getOrderStatus(order.status).color"
></p-tag>

Or work with NgTemplateOutlet.

<ng-container
  [ngTemplateOutlet]="orderStatuscontainer"
  [ngTemplateOutletContext]="{
    $implicit: getOrderStatus(order.status)
  }"
>
</ng-container>

<ng-template #orderStatuscontainer let-orderStatus>
  <p-tag
    [value]="orderStatus.status"
    [severity]="orderStatus.color"
  ></p-tag>
</ng-template>

Sample StackBlitz Demo

  • Related