Minja
Minja

Reputation: 1222

Angular 4 Custom decorator - injecting services

I want to create an authentication decorator in my application.

Usage example should be simple as

@RequireAuthentication()
@HostListener('click', ['$event']) onClick(event: Event) {
  // ...
}

As I know decorator can only be function, so in some other file I plan to have

export function RequireAuthentication() {
    if (!userService.isAuthenticated) {
        navigationService.goToLogin();
        return;
    }
}

The problem for me is how to properly initialize userService and navigationService in this case, since these services contain all logic for finding if a user is authenticated and showing login screen.

I already tried:

  1. to use a class with the constructor for service initialization, but then the nested method cannot be used as a decorator
  2. to use Injectable class to create services, I need to create an instance of this class, same problem.
  3. to use ModuleWithProviders approach to hide authentication implementation and only expose decorator, but not sure if that is the right way to do this.

Any hints would be helpful. Could be that I miss something fundamental since I'm not an experienced angular developer or there is another way to approach this problem.

Upvotes: 10

Views: 9701

Answers (1)

Estus Flask
Estus Flask

Reputation: 222429

As explained in this answer, the solution that is idiomatic to the framework is to expose injector class instance property, so it could be accessed inside decorator. The existence of injector property can be also secured with an interface.

Since property decorator runs once and has access to class prototype but not instance, it's necessary to patch ngOnOnit method and retrieve all necessary services inside patched method with this.injector.get().

The alternative is to expose global injector to some object, as explained here. This is not idiomatic solution but a hack that will result in certain limitations and negative consequences. It can hardly be recommended for use in production.

Upvotes: 8

Related Questions