In my angular 4 application , I am getting this weird error everytime my sidebar component renders. I don't have any attribute "name" in my code. Finding it hard to figure out why the error is being thrown. Below is the console error log. Any help is much appreciated.
html code:
<div class="sidebar" >
<app-sidebar></app-sidebar>
<div class="sidebar-background" style="background-image: url(assets/img/sidebar-1.jpg)"></div>
</div>
Error log :
ERROR TypeError: Cannot read property 'name' of undefined
at checkBindingNoChanges (core.js:9912)
at checkNoChangesNodeInline (core.js:13961)
at checkNoChangesNode (core.js:13935)
at debugCheckNoChangesNode (core.js:14764)
at debugCheckDirectivesFn (core.js:14666)
at Object.eval [as updateDirectives] (AppComponent.html:2)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:14648)
at checkNoChangesView (core.js:13773)
at callViewAction (core.js:14126)
at execComponentViewsAction (core.js:14078)
at checkNoChangesView (core.js:13776)
at callWithDebugContext (core.js:15049)
at Object.debugCheckNoChangesView [as checkNoChangesView] (core.js:14593)
at ViewRef_.webpackJsonp.../../../core/esm5/core.js.ViewRef_.checkNoChanges (core.js:11584)
at core.js:5903
View_AppComponent_0 @ AppComponent.html:2
proxyClass @ compiler.js:14645
webpackJsonp.../../../core/esm5/core.js.DebugContext_.logError @ core.js:14989
webpackJsonp.../../../core/esm5/core.js.ErrorHandler.handleError @ core.js:1501
(anonymous) @ core.js:5908
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:365
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run @ zone.js:125
webpackJsonp.../../../core/esm5/core.js.NgZone.runOutsideAngular @ core.js:4681
webpackJsonp.../../../core/esm5/core.js.ApplicationRef.tick @ core.js:5908
(anonymous) @ core.js:5734
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:365
onInvoke @ core.js:4733
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:364
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run @ zone.js:125
webpackJsonp.../../../core/esm5/core.js.NgZone.run @ core.js:4550
next @ core.js:5734
schedulerFn @ core.js:4319
webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.__tryOrUnsub @ Subscriber.js:239
webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.next @ Subscriber.js:186
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber._next @ Subscriber.js:126
webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:90
webpackJsonp.../../../../rxjs/Subject.js.Subject.next @ Subject.js:55
webpackJsonp.../../../core/esm5/core.js.EventEmitter.emit @ core.js:4299
checkStable @ core.js:4698
onHasTask @ core.js:4746
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.hasTask @ zone.js:418
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate._updateTaskCount @ zone.js:438
webpackJsonp.../../../../zone.js/dist/zone.js.Zone._updateTaskCount @ zone.js:262
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask @ zone.js:182
drainMicroTaskQueue @ zone.js:593
Promise resolved (async)
scheduleQueueDrain @ zone.js:552
scheduleMicroTask @ zone.js:560
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:387
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:209
webpackJsonp.../../../../zone.js/dist/zone.js.Zone.scheduleMicroTask @ zone.js:229
scheduleResolveOrReject @ zone.js:758
webpackJsonp.../../../../zone.js/dist/zone.js.ZoneAwarePromise.then @ zone.js:847
webpackJsonp.../../../core/esm5/core.js.PlatformRef.bootstrapModule @ core.js:5562
../../../../../src/main.ts @ main.ts:11
__webpack_require__ @ bootstrap 655e16dd1fe7443b4474:54
0 @ main.bundle.js:1835
__webpack_require__ @ bootstrap 655e16dd1fe7443b4474:54
webpackJsonpCallback @ bootstrap 655e16dd1fe7443b4474:25
(anonymous) @ main.bundle.js:1
AppComponent.html:2 ERROR CONTEXT
Complete TS :
import { Component, OnInit } from '@angular/core';
import { LabelsModel } from './../../core/models/labels';
import { LevelModel } from './../../core/models/level';
import { DataService } from './../../core/service/data.service';
import * as _ from 'underscore';
import { AppService } from './../../core/service/app.service';
import { CategoryModel } from './../../core/models/cat';
import { OnDestroy } from '@angular/core/src/metadata/lifecycle_hooks';
import { AttributeModel } from './../../core/models/att';
import { CountModel, CountChildModel } from './../../core/models/count';
import { SearchModel } from './../../core/models/search';
declare const $: any;
@Component({
selector: 'app-sidebar',
templateUrl: './sidebar.component.html',
styleUrls: ['./sidebar.component.css']
})
export class SidebarComponent implements OnInit {
menuItems: any[];
highlightedDiv: number;
productCategory: CategoryModel[];
productCategoryM: CategoryModel[];
productFiltered: AttributeModel[];
searchOrder = [];
productAttribute: AttributeModel[];
productAttributeM: AttributeModel[];
countModel: CountModel[];
countChildModel: Array<CountChildModel> = [];
countVal: any;
data = [];
searchArray = [];
searchModel: SearchModel = {};
childSearch: string[] = [];
productSelected: LevelModel;
searchCheck: SearchModel[];
checkB: boolean;
searchCheck1: SearchModel;
// productName: string;
filterSelected: boolean;
labelList: LabelsModel[] = [];
constructor(private _AppService: AppService, private _dataService: DataService) { }
ngOnInit() {
this._AppService.getData().subscribe(te => this.labelList = te);
this._dataService.productSelectedName.subscribe(product => this.productChange(product));
this._dataService.toggleValue.subscribe(toggleVal => this.changeToggle(toggleVal));
this._AppService.getCat$().subscribe(categoryValues => this.processCategory(categoryValues));
this._dataService.filterList.subscribe(filterValue => this.changeFilter(filterValue));
this._dataService.setFilterSelected(false);
this._dataService.filterSelect.subscribe(val => this.filterSelected = val);
}
isMobileMenu() {
if ($(window).width() > 991) {
return false;
} else {
return true;
}
};
changeToggle(toggle): void {
this.highlightedDiv = toggle;
}
clearFilters() {
this._dataService.setFilterList([]);
this._dataService.setFilterSelected(false);
this._dataService.setDisplay(0);
}
productChange(product) {
this.productSelected = {};
if (product === undefined || product == null) {
this.productSelected.level = 'level1';
this.productSelected.product = 'root';
} else {
this.productSelected = product;
}
if (this.productCategoryM !== undefined) {
this.processCategory(this.productCategoryM);
}
}
processCategory(categoryValues): void {
this.searchOrder = [];
this.productCategory = _.where(categoryValues, { id: this.productSelected.product });
this.productCategoryM = categoryValues;
for (const search of this.productCategory[0].search) {
this.searchOrder.push(search);
}
this._AppService.getAtt$().subscribe(attributeValues => this.processAttribute(attributeValues));
}
processAttribute(attributeValues): void {
const searchObj = {};
let filters = [];
this.productFiltered = [];
this.productAttributeM = attributeValues;
this.searchCheck = this._dataService.getFilterList();
searchObj[this.productSelected.level] = this.productSelected.product;
const searchKey = this.productSelected.level;
this.productAttribute = _.where(attributeValues, searchObj);
if (this._dataService.getFilterSelected() == true) {
filters = this._dataService.getFilterList();
for (let i = 0; i < filters.length; i++) {
for (let j = 0; j < filters[i].searchChild.length; j++) {
if (isNaN(+filters[i].searchChild[j])) {
searchObj[filters[i].searchParent] = filters[i].searchChild[j];
} else {
searchObj[filters[i].searchParent] = +filters[i].searchChild[j];
}
}
}
this.productFiltered.push.apply(this.productFiltered, (_.where(this.productAttribute, searchObj)));
this.productAttribute = _.unique(this.productFiltered);
}
this.countModel = [];
for (let i = 0; i < this.searchOrder.length; i++) {
this.checkB = false;
if (this.searchCheck !== undefined && this.searchCheck.length > 0) {
this.searchCheck1 = this.searchCheck.find(this.check, this.searchOrder[i]);
if (this.searchCheck1 !== undefined) {
if (this.searchCheck1.searchChild.length > 0) {
this.checkB = true;
}
}
}
this.countModel[i] = {};
this.countModel[i].parentName = this.searchOrder[i];
this.countVal = _.pairs(_.countBy(this.productAttribute, this.searchOrder[i]));
this.countChildModel = [];
for (let j = 0; j < this.countVal.length; j++) {
if (this.countVal[j][0] !== 'null'){
this.countChildModel[j] = {};
this.countChildModel[j].childName = this.countVal[j][0];
this.countChildModel[j].count = this.countVal[j][1];
if (this.checkB) {
if ((this.searchCheck.find(this.check, this.searchOrder[i]).searchChild.find
(this.check1, this.countVal[j][0])) !== undefined) {
this.countChildModel[j].check = true;
}
}
}
}
this.countModel[i].child = _.sortBy(this.countChildModel, 'childName');
}
for (let i = 0; i < this.countModel.length; i++) {
this.countModel[i].parentLabel = _.where(this.labelList, { id: this.countModel[i].parentName })[0].label;
}
}
check(ad) {
return ad.searchParent == this ? true : false;
}
check1(ad2) {
return ad2 == this ? true : false;
}
changeFilter(val) {
val.length == 0 ? this._dataService.setFilterSelected(false) : this._dataService.setFilterSelected(true);
this.processAttribute(this.productAttributeM);
}
taxonSelected(parent, taxon, checked) {
this.searchModel = {};
this.childSearch = [];
this.searchArray = [];
if (checked) {
this.searchArray = this._dataService.getFilterList();
if (_.where(this._dataService.getFilterList(), { searchParent: parent }).length > 0) {
this.childSearch = _.where(this._dataService.getFilterList(), { searchParent: parent })[0].searchChild;
this.searchArray.splice((this.searchArray.map(function (d) { return d['searchParent']; }).indexOf(parent)), 1);
this.childSearch.push(taxon.childName);
this.searchModel.searchChild = this.childSearch;
this.searchArray.push(this.searchModel);
this.searchModel.searchParent = parent;
this._dataService.setFilterList(this.searchArray);
} else {
this.childSearch.push(taxon.childName);
this.searchModel.searchChild = this.childSearch;
this.searchModel.searchParent = parent;
this.searchArray.push(this.searchModel);
this._dataService.setFilterList(this.searchArray);
}
} else {
this.childSearch = _.where(this._dataService.getFilterList(), { searchParent: parent })[0].searchChild;
if (this._dataService.getFilterList().length > 1) {
this.searchArray = this._dataService.getFilterList();
this.searchArray.splice((this.searchArray.map(function (d) { return d['searchParent']; }).indexOf(parent)), 1);
if (this.childSearch.length > 1) {
this.childSearch.splice(this.childSearch.indexOf(taxon.childName), 1);
this.searchModel.searchChild = this.childSearch;
this.searchModel.searchParent = parent;
this.searchArray.push(this.searchModel);
this._dataService.setFilterList(this.searchArray);
} else {
this._dataService.setFilterList(this.searchArray);
}
} else {
if (this.childSearch.length > 1) {
this.childSearch.splice(this.childSearch.indexOf(taxon.childName), 1);
this.searchModel.searchChild = this.childSearch;
this.searchModel.searchParent = parent;
this.searchArray.push(this.searchModel);
this._dataService.setFilterList(this.searchArray);
} else {
this._dataService.setFilterList([]);
}
}
}
}
ngOnDestroy(): void {
}
}
Complete side bar.html code :
<div class="logo">
<a href="" class="simple-text">
<div class="logo-img">
<img src="" />
</div>
Tenets Technologies
</a>
</div>
<div class="sidebar-wrapper scrollbar-danger" >
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 refine ">
<h6>Refine </h6>
</div>
<div class="col-lg-5 col-md-5 col-sm-5 clear text-right" (click) = "clearFilters()" *ngIf="filterSelected==true">
Clear All
<i class="material-icons">clear</i>
</div>
</div>
<div class="nav-container ">
<ul class="nav ">
<li routerlinkactive="active" *ngFor="let search of countModel" class="">
<a data-toggle="collapse" href="#{{search.parentName}}" class="">
<div class="row">
<div class="col-md-2 col-sm-2 col-xs-2 ">
<i class="material-icons">apps</i>
</div>
<div class="col-xs-8 col-sm-8 col-md-8">
<p class="test"> {{search.parentLabel}}</p>
</div>
<div class="col-md-2 col-sm-2 col-xs-2 ">
<b class="caret"></b>
</div>
</div>
</a>
<div class="collapse listCont scrollbar-danger" id="{{search.parentName}}">
<ul class="nav child">
<li routerlinkactive="active" *ngFor="let test of search.child">
<div class="checkbox">
<label>
<input type="checkbox" name="optionsCheckboxes" [checked]="test.check" (click)="taxonSelected(search.parentName,test, $event.target.checked)">
<span class="checkbox-label">
{{test.childName}} ({{test.count}})
</span>
</label>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
App.component.ts
import { Component, OnInit, ViewChild, AfterViewInit, ChangeDetectorRef } from '@angular/core';
import { Location, LocationStrategy, PathLocationStrategy, PopStateEvent } from '@angular/common';
import 'rxjs/add/operator/filter';
import { NavbarComponent } from './components/navbar/navbar.component';
import { Router, NavigationEnd, NavigationStart } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
import PerfectScrollbar from 'perfect-scrollbar';
import { DataService } from 'app/core/service/data.service';
import { MatSnackBar } from '@angular/material';
import { AppService } from 'app/core/service/app.service';
declare const $: any;
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
private _router: Subscription;
private lastPoppedUrl: string;
private yScrollStack: number[] = [];
/* headerValue = 0; */
toggleSide: number;
@ViewChild(NavbarComponent) navbar: NavbarComponent;
constructor(public location: Location, private router: Router,
private _dataService: DataService, private cdr: ChangeDetectorRef,private _AppService:AppService
) { }
ngOnInit() {
$.material.init();
this._dataService.toggleValue.subscribe(toggle => this.changeToggle(toggle));
const elemMainPanel = <HTMLElement>document.querySelector('.main-panel');
const elemSidebar = <HTMLElement>document.querySelector('.sidebar .sidebar-wrapper');
this._dataService.setDisplay(0);
/* this.headerValue = 0;
this._dataService.headerValue.subscribe(header => this.headerValue = header); */
this.location.subscribe((ev: PopStateEvent) => {
this.lastPoppedUrl = ev.url;
});
this.router.events.subscribe((event: any) => {
this.navbar.sidebarClose();
if (event instanceof NavigationStart) {
if (event.url != this.lastPoppedUrl)
this.yScrollStack.push(window.scrollY);
} else if (event instanceof NavigationEnd) {
if (event.url == this.lastPoppedUrl) {
this.lastPoppedUrl = undefined;
window.scrollTo(0, this.yScrollStack.pop());
} else
window.scrollTo(0, 0);
}
});
this._router = this.router.events.filter(event => event instanceof NavigationEnd).subscribe((event: NavigationEnd) => {
elemMainPanel.scrollTop = 0;
elemSidebar.scrollTop = 0;
});
if (window.matchMedia(`(min-width: 960px)`).matches && !this.isMac()) {
let ps = new PerfectScrollbar(elemMainPanel);
ps = new PerfectScrollbar(elemSidebar);
}
}
changeToggle(val) {
this.toggleSide = val;
this.isDetailsMenu();
}
isDetailsMenu() {
if (this.toggleSide == 1) {
return false;
} else {
return true;
}
}
ngAfterViewInit() {
this.runOnRouteChange();
}
runOnRouteChange(): void {
if (window.matchMedia(`(min-width: 960px)`).matches && !this.isMac()) {
const elemMainPanel = <HTMLElement>document.querySelector('.main-panel');
const ps = new PerfectScrollbar(elemMainPanel);
ps.update();
}
}
isMac(): boolean {
let bool = false;
if (navigator.platform.toUpperCase().indexOf('MAC') >= 0 || navigator.platform.toUpperCase().indexOf('IPAD') >= 0) {
bool = true;
}
return bool;
}
}
App.component.html
<div class="wrapper">
<div class="sidebar" >
<app-sidebar></app-sidebar>
<div class="sidebar-background" style="background-image: url(assets/img/sidebar-1.jpg)"></div>
</div>
<div class="main-panel" [ngClass]="{'dtl1': isDetailsMenu()}">
<app-navbar class="pos" [ngClass]="{'dtl-nav': isDetailsMenu()}"></app-navbar>
<app-app-filter ></app-app-filter>
<app-tree></app-tree>
<router-outlet></router-outlet>
<app-footer></app-footer>
</div>
</div>
I just got the issue as well, it seems that the error itself is a red herring, since the error is a bug in angular, check the following issues for more content
The actual underlying error is most probably the expressionChangedAfterItHasBeenCheckedError
. In development mode, angular goes over your bindings twice, the second time to check if they have the same value. If they don't have the same value, it assumes that reading the value modified those bindings and therefore throws the expressionChangedAfterItHasBeenCheckedError
- other sources of that exception could be if you have quite unstable values which are changing very often, try removing the bindings, than the error should disappear, than you're sure that it's the expressionChangedAfterItHasBeenCheckedError
long story short, don't care about the exception you posted, try to solve the expressionChangedAfterItHasBeenCheckedError
(google how it can happen and be resolved - there are tons of questions about that already on SO)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With