Cannot read property of undefined @ViewChild not working Angular 5
ViewChild
is expected to be used to get target element from current component's view(template) which matches the selector.
But according to your comment above, it seems there is no app-sidebar
placed in your header.component.html
, so ViewChild
is not able to get a valid element which results in your current error.
The solution should be place app-sidebar
at least once.
<app-sidebar></app-sidebar>
<div (click)="sidebar.sendData()"></div>
Angular 2 @ViewChild not working. Cannot Read Property "title" of Undefined
You should be checking for the @ViewChild
in the AfterViewChecked
instead of the AfterViewInit
. Also you can bundle your @angular/core
imports like so: import { Component, ViewChild, AfterViewInit } from '@angular/core';
. Then instead of implementing AfterViewInit
just implement AfterViewChecked
.
Here is how it could look:
import { AdminComponent } from 'admin/admin.component';
import { Component, ViewChild, AfterViewChecked } from '@angular/core';
@Component({
selector: 'monitor-header',
templateUrl: './header.monitor.component.html',
styleUrls: ['./header.monitor.component.css']
})
export class HeaderMonitorComponent implements AfterViewChecked {
@ViewChild(AdminComponent) private admin: AdminComponent;
private monitorTitle: string;
ngAfterViewChecked() {
this.monitorTitle = this.admin.title;
}
}
One question: Are these both parent components or will one of the components be a child of the other? The reason i ask is that you may want to look into a different method of passing that variable between components as this may be achieved with an @Input
or using a service to store and set the header variable. I hope this can be of some help.
EDIT:
To answer your comment, you should create a service like this:
import { Injectable } from '@angular/core';
@Injectable()
export class HeaderService {
_title: string;
constructor() { }
set title(title) {
this._title = title;
}
get title() {
return this._title;
}
}
Then in your component import the service and get
or set
the variable:
import { AdminComponent } from 'admin/admin.component';
import { Component, ViewChild, AfterViewChecked } from '@angular/core';
import { HeaderService } from 'path/to/your/service';
@Component({
selector: 'monitor-header',
templateUrl: './header.monitor.component.html',
styleUrls: ['./header.monitor.component.css']
})
export class HeaderMonitorComponent implements AfterViewChecked {
@ViewChild(AdminComponent) private admin: AdminComponent;
private monitorTitle: string;
constructor(private headerService: HeaderService) {} // Import service here
ngAfterViewChecked() {
this.monitorTitle = this.headerService.title;
}
}
You just need to make sure you set the title in one of the components using this.headerService.title = 'yourTitle';
I am just not sure which component gets loaded first.
You should check out Angular Services here: https://angular.io/tutorial/toh-pt4
Also check out Angular Component Interaction here: https://angular.io/guide/component-interaction
EDIT #2:
Here is another way to subscribe to that title in your Service:
So here below I have created a Subject
that is of type string, and a method that tells it here is the next string to hold and send.
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class HeaderService {
public titleSubject: Subject<string> = new Subject<string>();
constructor() { }
setNextTitle(title) {
this.titleSubject.next();
}
}
Then in your HeaderMonitorComponent
you would want to subscribe to that Subject
like so:
import { AdminComponent } from 'admin/admin.component';
import { Component, OnInit ViewChild, AfterViewChecked } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HeaderService } from 'path/to/your/service';
@Component({
selector: 'monitor-header',
templateUrl: './header.monitor.component.html',
styleUrls: ['./header.monitor.component.css']
})
export class HeaderMonitorComponent implements OnInit, AfterViewChecked {
@ViewChild(AdminComponent) private admin: AdminComponent;
private monitorTitle: string;
titleObservable: Observable<string>;
constructor(private headerService: HeaderService) {} // Import service here
ngOnInit() {
this.titleObservable = this.headerService.titleSubject.asObservable();
this.titleObservable.subscribe((title) => {
this.monitorTitle = title;
});
}
ngAfterViewChecked() {
this.monitorTitle = this.headerService.title;
}
}
Then in your AdminComponent
, whenever the button is clicked, call this.headerService.setNextTitle(title)
and the new title which you are subscribing to in the HeaderMonitorComponent will then be acknowledged and replace the current value of monitorTitle
.
Just another quick way to handle the data passing through.
@viewChild not working - cannot read property nativeElement of undefined
@ViewChild('keywords-input') keywordsInput;
doesn't match id="keywords-input"
id="keywords-input"
should be instead a template variable:
#keywordsInput
Note that camel case should be used, since -
is not allowed in template reference names.
@ViewChild()
supports names of template variables as string:
@ViewChild('keywordsInput') keywordsInput;
or component or directive types:
@ViewChild(MyKeywordsInputComponent) keywordsInput;
See also https://stackoverflow.com/a/35209681/217408
Hint:keywordsInput
is not set before ngAfterViewInit()
is called
Angular @ViewChild Error 'Cannot read property nativeElement of undefined"
You are facing this issue because of the *ngIf
directive won't create a DOM element until the condition becomes true
.
So instead of using the *ngIf
use hidden
property of HTML which will create DOM element but it won't show to the user until condition false
<div [hidden]="!normalDeviasiDaily">
<div #normalDeviasiDaily id="normalDeviasiDaily">
<canvas style="width:100%; height:400px;"></canvas>
</div>
</div>
<div [hidden]="normalDeviasiDaily">
<skeleton-item height="400px"></skeleton-item>
</div>
Hope this will help!
Angular 2 viewchild not working - cannot read property nativeElement of undefined
You need to change
ngOnInit() {
this.selectedCategories = [];
this.select.nativeElement.multiselect({
to
ngAfterViewInit() {
this.selectedCategories = [];
this.select.nativeElement.multiselect({
The nativeElement
isn't available before the view is initialized.
Related Topics
React Js - How to Get Click Event Values from Child Component to Parent Component
Finding the Symmetric Difference Between Two Arrays
Cannot Open Local File - Chrome: Not Allowed to Load Local Resource
Redirecting With JavaScript If a Radiobox Is Checked
Firebase.Firestore() Is Not a Function When Trying to Initialize Cloud Firestore
How to Convert Uint8 Array to Base64 Encoded String
Only Allowing Numbers Upto Certain Length in Material Ui
How to Fetch Url of Current Tab in My Chrome Extension Using JavaScript
How to Redirect to Another Component Onsubmit Search
Ngoninit Not Being Called When Injectable Class Is Instantiated
How to Block +,-,E in Input Type Number
Force Facebook to Open Link in External Browser for Smart Phones
Syntaxerror: Unexpected Token O in Json At Position 1
Json to CSV Flattening Nested Json
Export Array of Objects into Excel Using JavaScript
Discord.Js Sending Message to Specific Channel
Lodash Group by Multiple Properties If Property Value Is True