In my Angular 8 application, I faced an issue where the backend model and frontend model are not identical. For example, the backend model stores dates in SQL format while I needed them in a JavaScript friendly format on the frontend.
To tackle this problem, instead of creating a new property in the class for mapping the date, I considered using a decorator for the date property. Here's how it looks:
Method #1: Conventional Approach - Introduce a new created property with the correct date format:
export class Message {
id: number;
message: string;
visitor: Visitor;
createdAt: string; /* Backend model created date */
created: Date; /* Frontend JavaScript date */
}
/* API Call in Service */
public getMessages(visitor_id: number) : Observable<Messages> {
return this.httpClient.get<Messages>(`${API_URL}/api/SampleData/Messages?visitor=${visitor_id}`).pipe(
map(v => {
v.model.map(i => {
i.created = moment(i.createdAt.replace('T', ' '), 'YYYY-MM-DD HH:mm:ss').toDate() ;
return i;
})
return v;
})
);
}
Method #2: Cleaner Approach Using Property Decorators:
export class Message {
id: number;
message: string;
visitor: Visitor;
@DateTransform()
createdAt: string;
}
function DateTransform() {
return function (target: any, key: string) {
Object.defineProperty(target, key, {
configurable: false,
get: () => {
console.log('trying to get value:' + key); /* This line doesnt fire */
return moment(key.replace('T', ' '), 'YYYY-MM-DD HH:mm:ss').toDate()
}
});
}
}
/* And in the component html */
<span class="kt-chat__datetime">{{ message.createdAt | amTimeAgo }}</span>
The second method appears to be more appropriate, however, the getter function is not triggered, and the component template still displays the old value. Hence, I have the following questions:
- Why is the getter not being executed for the desired functionality?
- Can the getter return a different type (date) rather than the original string?
- Lastly, is utilizing decorators the correct approach in this scenario?
Thank you