Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call static function from angular2 template

Tags:

angular

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?

like image 318
lowcrawler Avatar asked Jan 25 '17 16:01

lowcrawler


People also ask

How to use static in TypeScript?

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.

Does TypeScript support static classes?

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.

What is static property in TypeScript?

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.

What are static functions?

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.


1 Answers

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)" 
like image 60
Günter Zöchbauer Avatar answered Sep 23 '22 08:09

Günter Zöchbauer