0

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);
  }
}
2
  • Can you provide the JSON response data for orders? Commented Jun 6, 2022 at 6:51
  • [ { "orderItems": [ "62932e65bec8a90c4cb11167", "62932e65bec8a90c4cb11168" ], "status": "Pending", "_id": "62932e65bec8a90c4cb11169", "shippingAddress1": "Street 45", "shippingAddress2": "1-B", "city": "Prague", "user": { "_id": "6293027ccf70a63e689dd8eb", "name": "mehedi", "id": "6293027ccf70a63e689dd8eb" }, "dateOrdered": "2022-05-29T08:27:17.618Z", "__v": 0, "id": "62932e65bec8a90c4cb11169" },] Commented Jun 6, 2022 at 7:09

2 Answers 2

1

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'
  }
};
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.