I have a spinner/loader element defined in app template (root component's template) like
<!--I have it here so that I don't have to paste it in all my templates-->
<div #spinner></div>
In my child components, I am trying to access it using @ViewChild but that seems to always return undefined. My code for accessing this in child component is
@ViewChild('spinner', { read: ViewContainerRef }) container: ViewContainerRef; //this is always undefined
However when I place my #spinner in my child component's HTML, it gets picked up correctly.
Is there a way to get the element defined in parent component in your child component as a ContainerRef?
I need the view reference to create the component on it dynamically using ComponentFactoryResolver.
It seems a similar issue but can't find a way to overcome.
EDIT: I am now using a shared service with the observable, but still it doesn't raise an event on .next.
Here is my code in SpinnerComponent
@Component({
selector: 'spinner',
styleUrls: ['app/styles/spinner.component.css'],
template:
`<div [hidden]="state.visible" class="in modal-backdrop spinner-overlay"></div>
<div class="spinner-message-container" aria-live="assertive" aria-atomic="true">
<div class="spinner-message" [ngClass]="spinnerMessageClass">{{ state.message }}</div>
</div>`
})
export class SpinnerComponent {
constructor(spinnerService: SpinnerService) {
spinnerService.spinnerStatus.subscribe(event => {
console.log('Event: ' + event); <= not getting called
this.state.visible = event;
});
}
public state = {
message: 'Please wait...',
visible: false
};
}
In SpinnerService, I have
@Injectable()
export class SpinnerService {
public events: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
public get spinnerStatus(): Observable<boolean> {
return this.events.asObservable();
}
public showSpinner() {
this.events.next(true);
}
public hideSpinner() {
this.events.next(false);
}
}
And in the calling component, I have
@Component({
selector: 'edit-auction',
templateUrl: '/auctions/edit.html'
})
export class EditAuctionComponent {
constructor(public spinnerService: SpinnerService) { }
ngAfterViewInit() {
//start the spinner
this.spinnerService.showSpinner();
}
}
In app.module.ts (root module)
@NgModule({
imports: [BrowserModule, FormsModule, HttpModule, routes],
declarations: [..],
providers: [NotificationsService, SpinnerService],
bootstrap: [AppComponent]
})
export class AppModule { }
@ViewChildcan only be used to select children. What are you trying to achieve with this? If you want to show/hide the spinner, why don't you use a custom spinner component into which you inject a service emitting events to show/hide the spinner. Check this out for an example: stackoverflow.com/a/42041945/1153681 - AngularChefshowSpinnerand its getting called - Ali Baig