When building components, defining the interfaces to be used by consumers is often challenging. We need to consider the information that must be passed between components and, at times, how it is processed.
At times, we expose interfaces solely due to an internal contract, but this is not an ideal approach. For instance, yesterday, I was constructing an article about the Kendo Scheduler. In my example, I developed an application that allows users to select course dates and add them to the calendar.
The calendar makes use of the Kendo Scheduler component, which requires a SchedulerEvent interface to display the event. In the context of my application, the key interface is 'Course.'
export type Course = {
id: string;
start: Date;
title: string;
description: string;
done: boolean;
};
When other developers work with the component, they should expect to pass an array of courses.
<courses-schedule [courses]="courses">
I wanted to display these courses in the Kendo Scheduler, but the contract with the Kendo Scheduler is slightly different because it uses the SchedulerEvent interface.
Why should I type my courses as a SchedulerEvent Interface?
How can I transform my courses into a Scheduler Interface?
Transform Inputs
From version 16.1.0, Angular introduced transform
a powerful and convenient feature for transforming input properties. This feature is particularly useful when you need to transform data.
@Input({ transform: toScheduleEvent }) courses: Course[] = [];
The transform option provides a straightforward method for data conversion. It will keep the signature with the courses interface and transform the course into the SchedulerEvent Interface. It makes the component user-friendly and simplifies the process of converting input data into other entities.
Read more about transform
Encapsulating Kendo's SchedulerEvent
We have two goals to reach:
Continue exposing my input property course with type
Course
.Transform the input courses into
SchedulerEvent
.
<app-calendar [courses]="courses"></app-calendar>
Using the transform
, we can convert the course data while hiding the mapping logic needed by the scheduler.
The input property maintains its type, while the transform employs the function toScheduleEvent
to execute the transformation.
@Input({ transform: toScheduleEvent }) courses: Course[] = [];
Within the toScheduleEvent
function, we utilize the map function to transform the course into the SchedulerEvent interface.
function toScheduleEvent(courses: Course[]): SchedulerEvent[] {
return courses.map(course => ({
id: course.id,
title: course.title,
start: course.start,
end: new Date(course.start.getTime() + 2 * 60 * 60 * 1000),
isAllDay: false
description: course.description
}));
}
The final code appears as follows:
import { Component, Input } from '@angular/core';
import { SchedulerEvent } from '@progress/kendo-angular-scheduler';
@Component({
selector: 'app-calendar',
standalone: true,
imports: [CommonModule, MonthViewModule, SchedulerModule],
templateUrl: './calendar.component.html',
styleUrls: ['./calendar.component.scss']
})
export class CalendarComponent {
@Input({ transform: toScheduleEvent }) courses: Course[] = [];
}
function toScheduleEvent(courses: Course[]): SchedulerEvent[] {
return courses.map(course => ({
id: course.id,
title: course.title,
start: course.start,
end: new Date(course.start.getTime() + 2 * 60 * 60 * 1000),
isAllDay: false
description: course.description
}));
}
Done! We've exposed the Course interface, but within my component, I maintain my contract with the Kendo Scheduler with no pain!
Recap
Done! Now, with this feature, we save time by not having to declare getters, and Angular assists us with a convenient method for transforming inputs. This simplifies data conversion and demonstrates how to encapsulate types and convert them to other types using the transform feature.
Happy Transform!!
Top comments (0)