Issue
Very new to Angular/TS and maybe I have phrased this wrong but I will try to explain as best I can.
I have 2 interfaces, one extends the other like this:
export interface CustomerModel {
firstName: string;
lastName: string;
//other things
}
export interface OrderModel extends Pick<CustomerModel, 'firstName' | 'lastName' {
orderNumber: number;
}
I have created a service with a hardcoded instance of Customer (working local on machine and for now everything is hardcoded. I will eventually work with DB but I need this to work this way first)
export class CustomerService {
customers: CustomerModel[];
constructor() {
this.customers = [{
firstName: 'John',
lastName: 'Doe',
//more here
},
{
firstName: 'Jane',
lastName: 'Smith',
//more here
},
]
}
getCustomers(): Observable<CustomerModel[]> {
const customers = of(customers);
return customers;
}
}
Now I am trying to create an Order Service using the OrderModel
export class OrderService {
orders: OrderModel[];
constructor() {
this.orders = [{
orderNumber: 123;
firstName: ???, //what do I put here to pick up the name from CustomerModel
lastName: ???,
},
{
//more here
},
]
}
getOrders(): Observable<OrderModel[]> {
const orders = of(orders);
return orders;
}
}
When I hover over the value of firstName in my orderservice, it does say it is from CustomerModel so I know that the extended worked.
If I leave firstName and lastName out of the orders array, I get an error saying that OrderModel is expecting them.
Maybe this is not possible and there is possibly a better solution but I have been going round in circle trying to see if this works.
Can anyone help me get the value of the property firstName/lastName from the CustomerModel?
Solution
Your best bet in this case is to have a separate file that holds all the base data for the user, and then transform that to whatever you need later.
// app/some-folder/customers.ts
export const customers: CustomerModel[] = [
{
firstName: 'John',
lastName: 'Doe',
//more here
},
{
firstName: 'Jane',
lastName: 'Smith',
//more here
},
];
And in the service
import { customers } from '@app/some-folder/customers.ts'
export class CustomerService {
public getCustomers(): Observable<CustomerModel[]> {
return of(customers);
}
}
import { customers } from '@app/some-folder/customers.ts'
// map the existing customers, and transform it to also have an orderNumber
// use ...a, orderNumber: i to merge the whole customer add orderNumber together
const orders: OrderModel[] = customers.map((a, i) => ({
firstName: a.firstName,
lastName: a.lastName,
orderNumber: i,
}))
// or you can do this, which is more in-line with how an API would respond
// generally an order would just include the customerId, or have a customer object
// const orders = customers.map((a, i) => ({ customer: a, orderNumber: i }))
export class OrderService {
public getOrders(): Observable<OrderModel[]> {
return of(orders);
}
}
This way when you implement the API, all you have to do is swap out the bodies of your functions.