Marley Marley - 1 month ago 23
TypeScript Question

No provider for the Modal Angular2

I'm trying to use optional parameters here in the constructor of the directive but have been unsuccessful all the times because of the error "No provider for Modal".

I have a Modal class with a component and I am subscribing to the modal.shown() to focus in my directive. Now, I want to use the same directive to even force focus on some other elements. So, I planned to use the optional arguments for the modal so that it works only when the constructor is passed that argument.

I did the following:

import { Directive, ElementRef, OnDestroy } from "@angular/core";
import { Subscription } from 'rxjs/Rx';
import { Modal } from "./modal";
import * as ng from "@angular/core";
import { Inject } from "@angular/core";

@Directive({
selector: "[tabFocus]"
})

export class Focus implements ng.OnDestroy, ng.OnInit {
private _subscription: Subscription;
constructor(private _el: ng.ElementRef, @Inject(Modal) private modal?: Modal) {
if (this.modal != undefined) {
this._subscription = this.modal.shown.subscribe(() => this._el.nativeElement.focus());
}
}

ngOnInit() {
this._el.nativeElement.focus();
}

ngOnDestroy() {
this._subscription.unsubscribe();
}

}


This works great in the case of the Modal i.e., when I use the directive tabFocus to the html element of the modal, the focus goes there perfectly. But whenever I use the directive for an another button element, the code breaks and I get the error "No Provider for Modal".

What I want to achieve in simple words is: I want to be able to use the same directive for two different purposes. 1) When there is a modal, the element on the modal should get the focus. 2) When there is no modal, and the directive is attached to an element, that element should just get the focus.

Answer

Actually, you could simply use the Angular Way of defining the Optional arguments. Right now ?: is typescript way of defining optional arguments.

import { Optional } from "@angular/core";

Add @Optional() in front of the private modal: Modal

and check if this.modal is true i.e.,

if(this.modal){
 //do something.
}

This should do the trick. Hope it helps.