I'm trying to build 'utility' services (classes) for an angular project. The utility classes have static functions (so we don't have to instantiate needless objects). One example is this:
import { Injectable } from '@angular/core'; @Injectable() export class DateService { constructor() { } public static parseDate(dateString: string): Date { if (dateString) { return new Date(dateString); } else { return null; } } }
In my component class file, I then import it like so:
import { DateService } from '../utilities/date.service';
and within the class code like this works:
ngOnInit():void { let temp = DateService.parseDate("2012/07/30"); console.log(temp); // Mon Jul 30 2012 00:00:00 GMT-0500 (Central Daylight Time) }
However, I would like to be able to use these utility functions within the angular html template, like so:
<label for="date">Date</label> <input type="date" class="form-control" id="date" required [value]="event.date | date: 'yyyy-MM-dd'" (input)="event.date=DateService.parseDate($event.target.value)" name="date">
Unfortunately, that does not work; giving a "Cannot read property 'parseDate' of undefined" error.
Now, I can move the 'parseDate' function to the component class, and that works fine (with the required change in the template, of course)... however, if I have a bunch of components, they'd all need to have their own 'parseDate' function and I think we all know that's a bad idea that doesn't scale well. (please ignore the trivial nature of the parseDate function)
Further, even though I don't really want to instantiate an object just to run a static function, I try it with actual dependency injection. Adding it to the providers array, and building a instance in the constructor - like so:
constructor(private _dateService: DateService) { }
and then changing my template to:
label for="date">Date</label> <input type="date" class="form-control" id="date" required [value]="event.date | date: 'yyyy-MM-dd'" (input)="event.date=_dateService.parseDate($event.target.value)" name="date">
This also fails, this time with a with a "self.context._dateService.parseDate is not a function" error. Removing the 'static' from the function fixes the problem and I could move on, but I'm still left needing to instantiate something just to run what should be just a static function. Surely there is a better way.
Thoughts?
A static method uses the static keyword instead of the function keyword when we define it. Static members can be encapsulated with the public, private and protected modifiers. We call a static method directly on the class, using the class name and dot notation. We don't need to create an object instance.
In TypeScript, we don't have a construct called the static class , and a class with only one instance is often represented as a regular object. We don't need static class syntax in TypeScript because a top-level function (or even an object) will do the job just as well.
With TypeScript, we can designate members as instance variables, which don't have the keyword static before them, and static members, which have the keyword static keyword before them. Static members can be accessed without having the class instantiated.
A static method (or static function) is a method defined as a member of an object but is accessible directly from an API object's constructor, rather than from an object instance created via the constructor.
Only instance members of the components class can be called from the view.
If you want to call static members, you need to provide a getter in the component.
export class MyComponent { parseDate = DateService.parseDate; }
then you can use it like
(input)="event.date=parseDate($event.target.value)"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With