Angular Data Models with Deserialization
Angular models are useful to get consistent data for your application with proper format.
Let's assume we've got an API (productdetails) which returns our product details of each product:
productinfo: {
Category: "appliances"
CurrencyCode: "INR"
DateOfEntry: "2019-08-26T00:00:00.000Z"
DateOfSale: "2017-04-17"
Description: "Bring home the Mi LED Smart TV 4A PRO and transform your movie- watching experience. This LED TV comes with an 80-cm (32) Ultra-bright HD-Ready Display, a 64-bit quad-core processor, and stereo speakers which provide a cinematic experience right in the comfort of your home. Also, with features such as PatchWall and Google Assistant, your TV-watching experience is made even more convenient."
Name: "Mi LED Smart TV 4A PRO 80 cm"
Price: 12499
ProductPicUrl: "mi-l32m5-al-original-imafj2cbhhsn3zje.jpeg"
Quantity: 5
Status: "Available"
SubCategory: "television"
SupplierName: "Very Best Screens"
WeightMeasure: 3.855
WeightUnit: "KG"
deliveryPrice: 0
_id: "5d63dc14e7179a084ef3ae49"
}
We are getting product details inside productinfo object.
Response without Models
Deserialization
We want to deserialize our JSON to our objects. Let's create an interface which provides an API for deserialization:
Response with Models
You can see the diference in response. With model, we are getting Product object as a response not just JSON object.
deserializable.model.ts
export interface Deserializable {
deserialize(input: any): this;
}
Recommended by LinkedIn
product.model.ts
import { Deserializable } from '@ecommerce/models/deserializable.model';
export class Product implements Deserializable {
public _id: string;
public Category?: string;
public CurrencyCode?: string;
public DateOfEntry?: string;
public DateOfSale?: string;
public Description?: string;
public Price?: number;
public ProductPicUrl?: string;
public Quantity?: number;
public Status?: string;
public SubCategory?: string;
public SupplierName?: string;
public WeightMeasure?: number;
public WeightUnit?: string;
public deliveryPrice?: number;
deserialize(input: any) {
Object.assign(this, input);
return this;
}
getWeight() {
return this.WeightMeasure + ' ' + this.WeightUnit;
}
}
Now we can go back to our api service and want to get an array of Product, not just objects:
getProductDetails(id: string): Observable<Product> {
const apiURL = `${this._appConfig.apiEndpoint}${this._appConfig.API_PRODUCT_DETAILS_PATH}`;
const authData = {productid : id};
return this.http.post<Product>(apiURL, authData)
.pipe(map(response => new Product().deserialize(response['productinfo']))
);
}
I am passing response['productinfo'] instead of response because i already mentioned response of product details is coming inside productinfo object. So i pass only response['productino'], then only product object will be passed through deserialize method.
But why should use this ?
Handling raw JSON objects is really painful and hard to maintain. Having "real" entity objects which store data has obvious advantages (maintaining and extensibility) - an example:
Suppose Product have a WeightMeasure and a WeightUnit. If you're handling the raw JSON you'll have to print out the weight of your product within your templates like this:
<tr>
<td>Weight :</td>
<td>{{productDt.WeightMeasure}} {{productDt.WeightUnit}}</td>
</tr>
But if your product is a Product object, you can simply implement a function to print the weight like this:
<tr>
<td>Weight :</td>
<td>
{{productDt.getWeight()}}
</td>
</tr>
My Source Code : https://github.com/piyalidas10/Ecommerce
Reference URL :