I have a toast notification component called ToastComponent
which I want to call from any other component. I implemented it like this:
ToastComponent
:
export class ToastComponent implements OnInit {
constructor() {}
showToast() {
// some code
}
}
app.component.html
:
<llqa-main-container>
<llqa-header></llqa-header>
<div class="content-container">
<main class="content-area">
<llqa-toast></llqa-toast> <!-- ToastComponent which I want to call -->
<router-outlet></router-outlet>
</main>
</div>
</llqa-main-container>
UserManagementComponent
which is inside the <router-outlet>
:
export class UserManagementComponent implements OnInit {
@ViewChild(ToastComponent) toast: ToastComponent;
constructor() {}
someSaveMethod() {
this.toast.showToast() // throws error below
}
}
On calling the someSaveMethod()
method, I'll get the error that toast
is undefined.
If I take <llqa-toast></llqa-toast>
out of the app.component.html
and put it on top of the user-management.component.html
, it works fine, but then I have to put it in every component. How can I get this to work?
Since in your case, the ToastComponent
is used in the grand parent (AppComponent
), that's why you are getting this error. One way to avoid this error is to use Subject
defined in some shared service. I am using that approach in my project to show toast notifications. Here is how you can do it:
Keep your <llqa-toast></llqa-toast>
in app.component.html
.
Define a service to basically emit an event and subscribe to that event in your ToastComponent
. For example,
UtilityService:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class UtilityService {
public OnShowToast = new Subject<boolean>();
public showToast(): void {
this.OnShowToast.next(true);
}
}
You need to inject this service in your AppModule
providers. Now subscribe
to the OnShowToast
event in your ToastComponent
.
ToastComponent:
import { UtilityService } from './path/to/the/utility.service';
export class ToastComponent implements OnInit {
constructor(private readonly utilityService: UtilityService) { }
ngOnInit() {
this.utilityService.OnShowToast.subscribe(value =>
{
this.showToast();
});
}
private showToast() {
// some code
}
}
Now, you can call the showToast()
method of the UtilityService
from any component you want. For example,
UserManagementComponent
export class UserManagementComponent implements OnInit {
// You dont need this now
// @ViewChild(ToastComponent) toast: ToastComponent;
constructor(private readonly utilityService: UtilityService) {}
someSaveMethod() {
this.utilityService.showToast();
}
}
来源:https://stackoverflow.com/questions/45709725/angular-4-viewchild-component-is-undefined