I have an Order
object and a Customer Object. The JSON payload
for the Order
object is like the following:
{
"order_number" : 1,
"customer_id": 1
}
And this is the JSON payload
for the Customer
object
{
"customer_id": 1,
"customer_name" : 1,
}
I have Orders page where I want to display the list of orders. But instead of order.customer_id
it was to display the customer_name
For the I have getCustomerById
which takes the customer_id
as a parameter and returns the customer_name
.
This is my OrdersPage
class:
import { Component, OnInit } from '@angular/core';
import { OrderService } from '../../services/order.service';
import { Order } from '../../models/order.model';
import { NavController, LoadingController } from '@ionic/angular';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { CustomerService } from 'src/app/services/customer.service';
import { Customer } from 'src/app/models/customer.model';
@Component({
selector: 'app-orders',
templateUrl: './orders.page.html',
styleUrls: ['./orders.page.scss'],
})
export class OrdersPage implements OnInit {
sender;
customerName: string;
destinationName: string;
// viewOrders = false;
error;
orders: Order[];
subscription: Subscription;
constructor(private orderService: OrderService,
private navCtrl: NavController,
private router: Router,
private customerService: CustomerService
) { }
ngOnInit() {
this.orderService.refreshNeeded
.subscribe(() => {
this.getAllOrders();
});
this.getAllOrders();
}
getAllOrders() {
this.orderService.getAllOrders().subscribe(
(res: Order[]) => {
this.orders = res;
},
(error) => {
this.error = error;
});
}
getCustomerById(customerId: number): string {
this.customerService.getCustomerById(customerId).subscribe(
(customer: Customer) => {
this.customerName = customer.name;
}
);
return this.customerName;
}
}
This is orders.page.html
<ion-header>
<ion-toolbar color="dark">
<ion-button slot="end">
<ion-menu-button> </ion-menu-button>
</ion-button>
<ion-title>Orders</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-row>
<ion-col size-md="8" offset-md="2">
<ion-row class="header-row ion-text-center">
<ion-col>
Order number
</ion-col>
<ion-col>
Customer
</ion-col>
</ion-row>
<ion-row *ngFor="let order of orders; let i = index" class="data-row ion-text-center">
<ion-col>
{{order.order_number}}
</ion-col>
<ion-col>
{{order.customer_id}}
</ion-col>
<!-- <ion-col>
{{getCustomerById(order?.customer_id)}}
</ion-col> -->
</ion-row>
</ion-col>
</ion-row>
</ion-content>
This html works but it returns the order.customer_id
not the customer_name
I have tried to get the name by calling the funtion in the template this way {{getCustomerById(order?.customer_id)}}
doesn't work and no error in the console as well.
What is the best way to get the customer_name
field in the order list?
This is my customer.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, Subject } from 'rxjs';
import { Customer } from '../models/customer.model';
import { catchError, tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class CustomerService {
url = 'http://api.mydomain.com';
constructor( ) { }
getAllCustomers(): Observable<Customer[]> {
return this.httpClient.get<Customer[]>(`${this.url}/customers`).pipe();
}
getCustomerById(id: number): Observable<Customer> {
return this.httpClient.get<Customer>(`${this.url}/customer/${id}`).pipe();
}
}
As mentionned by @Muhammad Umair it is not a good design to make a request to a server for each customer name. Best is to make one request to fetch all wanted curstomer names. The solution below do not take this into consideration.
Best here is to use a pipe.
"A pipe takes in data as input and transforms it to a desired output." Angular doc
Notice that your request to get your curstomer name is asynchronous (this is why nothing is displayed in your template), here you need to use the async pipe as well :
<ion-col>
{{ order.customer_id | getCustomerName | async }}
</ion-col>
And here is the pipe (that you should insert into your declarations in your component's module.
import { Pipe } from '@angular/core';
@Pipe({
name: 'getCustomerName'
})
export class CustomerNamePipe {
constructor(private customerService: CustomerService) { }
transform(userIds, args) {
return this.customerService.getCustomerById(curstomerId);
}
}