Angular array changes detection
I am a beginner with Angular, and i can't find proper solution for my problem.
I have a component containing table filled with list of items (each item in list is in another component), and there is third component containing filter. Filter contains multiple checkboxes and a filter button.
I send boolean array of checkboxes states from filterComponent through itemsListComponent to singleItemComponent and it works fine. My problem is changes detection. When I used NgDoCheck with differs it works always when I click at checkbox and filter button instead only filter button.
I tried NgOnChanges but it worked only once and then it didn't see any changes of values into array.
This is my SingleItemsComponent (I think you don't need others to help me solve this). Look at this and show me any example of solving this problem please.
import { Component, OnInit, OnChanges,ViewChild, AfterViewInit, Inject, Input, DoCheck, KeyValueDiffer, KeyValueDiffers, SimpleChanges, SimpleChange, ChangeDetectionStrategy, ChangeDetectorRef, IterableDiffers } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { MatTableDataSource, MatPaginator, MatSort, throwToolbarMixedModesError } from '@angular/material';
import { IPOLine } from 'src/app/models/po-line';
import { POLineService } from 'src/app/services/po-line.service';
@Component({
selector: 'app-po-lines-list',
templateUrl: './po-lines-list.component.html',
styleUrls: ['./po-lines-list.component.css'],
animations: [
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0', display: 'none' })),
state('expanded', style({ height: '*' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
]),
],
})
export class POLinesListComponent implements OnInit, DoCheck{
isLogged = false;
login: string;
dataSource = new MatTableDataSource<IPOLine>();
expandedElement: IPOLine;
errorMessage: string;
response: any;
today = new Date(); // (1990, 0, 1);
isLoadingList = true;
differ: any;
@Input() sentData: boolean;
_sentData = this.sentData;
ngDoCheck(){
var changes = this.differ.diff(this._sentData);
if (changes){
console.log('changes detected changes detected changes detected changes detected changes detected ');
}
else
console.log('changes not detected changes not detected changes not detected changes not detected ');
}
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(
//private cd: ChangeDetectorRef,
private differs: KeyValueDiffers,
private _POLineService: POLineService,
private activatedRoute: ActivatedRoute) {
this.differ = differs.find({}).create();
}
ngOnInit() {
// Assign the data to the data source for the table to render
this.login = this.activatedRoute.snapshot.paramMap.get('login');
this._POLineService.getUserPOLines(this.login)
.subscribe(data => {
this.dataSource.data = data;
},
error => {
this.errorMessage = <any>error;
this.isLoadingList = false;
}
,
() => {
// console.log('eee' + this.dataSource.data);
this.isLoadingList = false;
this.dataSource.data.forEach(x => x.isExpired = new Date(x.PromisedDate) < new Date() ? true : false);
}
);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
}
I'm sorry for the mess in a code but I tried so many things i don't even remember what was what. Thanks for any help.
FilterComponent.ts:
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
@Component({
selector: 'app-filters',
templateUrl: './filters.component.html',
styleUrls: ['./filters.component.css']
})
export class FiltersComponent implements OnInit {
@Output() filterByClass = new EventEmitter();
filterByTTR = false;
filterByTBR = false;
filters:boolean = ;
constructor() { }
ngOnInit() {
}
log() {
if(!this.filterByTTR)
console.log('TTR not checked');
else
console.log('TTR checked');
if (!this.filterByTBR)
console.log('TBR not checked');
else
console.log('TBR checked');
this.filters[0] = this.filterByTTR;
this.filters[1] = this.filterByTBR;
this.filterByClass.emit(this.filters);
}
Part of FilterComponent.html:
<mat-card-content class="col">
<mat-checkbox [checked]="filterByTTR" (change)="filterByTTR = !filterByTTR">TTR</mat-checkbox>
<mat-checkbox [checked]="filterByTBR" (change)="filterByTBR = !filterByTBR">TBR</mat-checkbox>
<!-- <mat-checkbox [(ngModel)]="filterByTBR"ref-TBR>TBR</mat-checkbox> -->
<div class="d-flex justify-content-between">
<button mat-raised-button color="primary">Clear</button>
<button mat-raised-button (click)="log()" color="primary">Apply</button>
</div>
PoLinesCompoenent.ts:
import { Component, OnInit, NgModule, ViewChild, Input } from
'@angular/core';
@Component({
selector: 'app-po-lines',
templateUrl: './po-lines.component.html',
styleUrls: ['./po-lines.component.css']
})
export class POLinesComponent implements OnInit {
count: boolean;
constructor() { }
ngOnInit(){}
displayCounter(count) {
console.log('first value is: ' + count[0] + ' second value is: ' + count[1]);
this.count = count;
}
PoLinesComponent.html:
<div class="container">
<div class="row">
<div class="side-bar col">
<app-filters (data)='displayCounter($event)'></app-filters>
</div>
<div class="content col">
<app-po-lines-list [sentData]="count"></app-po-lines-list>
</div>
</div>
</div>
angular ngoninit ngonchanges
|
show 3 more comments
I am a beginner with Angular, and i can't find proper solution for my problem.
I have a component containing table filled with list of items (each item in list is in another component), and there is third component containing filter. Filter contains multiple checkboxes and a filter button.
I send boolean array of checkboxes states from filterComponent through itemsListComponent to singleItemComponent and it works fine. My problem is changes detection. When I used NgDoCheck with differs it works always when I click at checkbox and filter button instead only filter button.
I tried NgOnChanges but it worked only once and then it didn't see any changes of values into array.
This is my SingleItemsComponent (I think you don't need others to help me solve this). Look at this and show me any example of solving this problem please.
import { Component, OnInit, OnChanges,ViewChild, AfterViewInit, Inject, Input, DoCheck, KeyValueDiffer, KeyValueDiffers, SimpleChanges, SimpleChange, ChangeDetectionStrategy, ChangeDetectorRef, IterableDiffers } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { MatTableDataSource, MatPaginator, MatSort, throwToolbarMixedModesError } from '@angular/material';
import { IPOLine } from 'src/app/models/po-line';
import { POLineService } from 'src/app/services/po-line.service';
@Component({
selector: 'app-po-lines-list',
templateUrl: './po-lines-list.component.html',
styleUrls: ['./po-lines-list.component.css'],
animations: [
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0', display: 'none' })),
state('expanded', style({ height: '*' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
]),
],
})
export class POLinesListComponent implements OnInit, DoCheck{
isLogged = false;
login: string;
dataSource = new MatTableDataSource<IPOLine>();
expandedElement: IPOLine;
errorMessage: string;
response: any;
today = new Date(); // (1990, 0, 1);
isLoadingList = true;
differ: any;
@Input() sentData: boolean;
_sentData = this.sentData;
ngDoCheck(){
var changes = this.differ.diff(this._sentData);
if (changes){
console.log('changes detected changes detected changes detected changes detected changes detected ');
}
else
console.log('changes not detected changes not detected changes not detected changes not detected ');
}
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(
//private cd: ChangeDetectorRef,
private differs: KeyValueDiffers,
private _POLineService: POLineService,
private activatedRoute: ActivatedRoute) {
this.differ = differs.find({}).create();
}
ngOnInit() {
// Assign the data to the data source for the table to render
this.login = this.activatedRoute.snapshot.paramMap.get('login');
this._POLineService.getUserPOLines(this.login)
.subscribe(data => {
this.dataSource.data = data;
},
error => {
this.errorMessage = <any>error;
this.isLoadingList = false;
}
,
() => {
// console.log('eee' + this.dataSource.data);
this.isLoadingList = false;
this.dataSource.data.forEach(x => x.isExpired = new Date(x.PromisedDate) < new Date() ? true : false);
}
);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
}
I'm sorry for the mess in a code but I tried so many things i don't even remember what was what. Thanks for any help.
FilterComponent.ts:
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
@Component({
selector: 'app-filters',
templateUrl: './filters.component.html',
styleUrls: ['./filters.component.css']
})
export class FiltersComponent implements OnInit {
@Output() filterByClass = new EventEmitter();
filterByTTR = false;
filterByTBR = false;
filters:boolean = ;
constructor() { }
ngOnInit() {
}
log() {
if(!this.filterByTTR)
console.log('TTR not checked');
else
console.log('TTR checked');
if (!this.filterByTBR)
console.log('TBR not checked');
else
console.log('TBR checked');
this.filters[0] = this.filterByTTR;
this.filters[1] = this.filterByTBR;
this.filterByClass.emit(this.filters);
}
Part of FilterComponent.html:
<mat-card-content class="col">
<mat-checkbox [checked]="filterByTTR" (change)="filterByTTR = !filterByTTR">TTR</mat-checkbox>
<mat-checkbox [checked]="filterByTBR" (change)="filterByTBR = !filterByTBR">TBR</mat-checkbox>
<!-- <mat-checkbox [(ngModel)]="filterByTBR"ref-TBR>TBR</mat-checkbox> -->
<div class="d-flex justify-content-between">
<button mat-raised-button color="primary">Clear</button>
<button mat-raised-button (click)="log()" color="primary">Apply</button>
</div>
PoLinesCompoenent.ts:
import { Component, OnInit, NgModule, ViewChild, Input } from
'@angular/core';
@Component({
selector: 'app-po-lines',
templateUrl: './po-lines.component.html',
styleUrls: ['./po-lines.component.css']
})
export class POLinesComponent implements OnInit {
count: boolean;
constructor() { }
ngOnInit(){}
displayCounter(count) {
console.log('first value is: ' + count[0] + ' second value is: ' + count[1]);
this.count = count;
}
PoLinesComponent.html:
<div class="container">
<div class="row">
<div class="side-bar col">
<app-filters (data)='displayCounter($event)'></app-filters>
</div>
<div class="content col">
<app-po-lines-list [sentData]="count"></app-po-lines-list>
</div>
</div>
</div>
angular ngoninit ngonchanges
Do you want to detect change when@Input() sentData: boolean;
from the outside changes?
– Nabil Shahid
Nov 14 '18 at 12:06
Exactly, I'm trying to detect changes in the other component. Do you know what's wrong here?
– Mystax
Nov 14 '18 at 12:10
Ok so basically you want to perform some action in the POLinesListComponent whensentData
is changed via a parent component right?
– Nabil Shahid
Nov 14 '18 at 12:14
That's it, I select checkboxes, click filter button, and then array with their states goes to PoLinesComponent which is a parent component of PoLinesListComponent and FilterComponent.
– Mystax
Nov 14 '18 at 12:19
Got it. See my answer
– Nabil Shahid
Nov 14 '18 at 12:34
|
show 3 more comments
I am a beginner with Angular, and i can't find proper solution for my problem.
I have a component containing table filled with list of items (each item in list is in another component), and there is third component containing filter. Filter contains multiple checkboxes and a filter button.
I send boolean array of checkboxes states from filterComponent through itemsListComponent to singleItemComponent and it works fine. My problem is changes detection. When I used NgDoCheck with differs it works always when I click at checkbox and filter button instead only filter button.
I tried NgOnChanges but it worked only once and then it didn't see any changes of values into array.
This is my SingleItemsComponent (I think you don't need others to help me solve this). Look at this and show me any example of solving this problem please.
import { Component, OnInit, OnChanges,ViewChild, AfterViewInit, Inject, Input, DoCheck, KeyValueDiffer, KeyValueDiffers, SimpleChanges, SimpleChange, ChangeDetectionStrategy, ChangeDetectorRef, IterableDiffers } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { MatTableDataSource, MatPaginator, MatSort, throwToolbarMixedModesError } from '@angular/material';
import { IPOLine } from 'src/app/models/po-line';
import { POLineService } from 'src/app/services/po-line.service';
@Component({
selector: 'app-po-lines-list',
templateUrl: './po-lines-list.component.html',
styleUrls: ['./po-lines-list.component.css'],
animations: [
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0', display: 'none' })),
state('expanded', style({ height: '*' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
]),
],
})
export class POLinesListComponent implements OnInit, DoCheck{
isLogged = false;
login: string;
dataSource = new MatTableDataSource<IPOLine>();
expandedElement: IPOLine;
errorMessage: string;
response: any;
today = new Date(); // (1990, 0, 1);
isLoadingList = true;
differ: any;
@Input() sentData: boolean;
_sentData = this.sentData;
ngDoCheck(){
var changes = this.differ.diff(this._sentData);
if (changes){
console.log('changes detected changes detected changes detected changes detected changes detected ');
}
else
console.log('changes not detected changes not detected changes not detected changes not detected ');
}
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(
//private cd: ChangeDetectorRef,
private differs: KeyValueDiffers,
private _POLineService: POLineService,
private activatedRoute: ActivatedRoute) {
this.differ = differs.find({}).create();
}
ngOnInit() {
// Assign the data to the data source for the table to render
this.login = this.activatedRoute.snapshot.paramMap.get('login');
this._POLineService.getUserPOLines(this.login)
.subscribe(data => {
this.dataSource.data = data;
},
error => {
this.errorMessage = <any>error;
this.isLoadingList = false;
}
,
() => {
// console.log('eee' + this.dataSource.data);
this.isLoadingList = false;
this.dataSource.data.forEach(x => x.isExpired = new Date(x.PromisedDate) < new Date() ? true : false);
}
);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
}
I'm sorry for the mess in a code but I tried so many things i don't even remember what was what. Thanks for any help.
FilterComponent.ts:
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
@Component({
selector: 'app-filters',
templateUrl: './filters.component.html',
styleUrls: ['./filters.component.css']
})
export class FiltersComponent implements OnInit {
@Output() filterByClass = new EventEmitter();
filterByTTR = false;
filterByTBR = false;
filters:boolean = ;
constructor() { }
ngOnInit() {
}
log() {
if(!this.filterByTTR)
console.log('TTR not checked');
else
console.log('TTR checked');
if (!this.filterByTBR)
console.log('TBR not checked');
else
console.log('TBR checked');
this.filters[0] = this.filterByTTR;
this.filters[1] = this.filterByTBR;
this.filterByClass.emit(this.filters);
}
Part of FilterComponent.html:
<mat-card-content class="col">
<mat-checkbox [checked]="filterByTTR" (change)="filterByTTR = !filterByTTR">TTR</mat-checkbox>
<mat-checkbox [checked]="filterByTBR" (change)="filterByTBR = !filterByTBR">TBR</mat-checkbox>
<!-- <mat-checkbox [(ngModel)]="filterByTBR"ref-TBR>TBR</mat-checkbox> -->
<div class="d-flex justify-content-between">
<button mat-raised-button color="primary">Clear</button>
<button mat-raised-button (click)="log()" color="primary">Apply</button>
</div>
PoLinesCompoenent.ts:
import { Component, OnInit, NgModule, ViewChild, Input } from
'@angular/core';
@Component({
selector: 'app-po-lines',
templateUrl: './po-lines.component.html',
styleUrls: ['./po-lines.component.css']
})
export class POLinesComponent implements OnInit {
count: boolean;
constructor() { }
ngOnInit(){}
displayCounter(count) {
console.log('first value is: ' + count[0] + ' second value is: ' + count[1]);
this.count = count;
}
PoLinesComponent.html:
<div class="container">
<div class="row">
<div class="side-bar col">
<app-filters (data)='displayCounter($event)'></app-filters>
</div>
<div class="content col">
<app-po-lines-list [sentData]="count"></app-po-lines-list>
</div>
</div>
</div>
angular ngoninit ngonchanges
I am a beginner with Angular, and i can't find proper solution for my problem.
I have a component containing table filled with list of items (each item in list is in another component), and there is third component containing filter. Filter contains multiple checkboxes and a filter button.
I send boolean array of checkboxes states from filterComponent through itemsListComponent to singleItemComponent and it works fine. My problem is changes detection. When I used NgDoCheck with differs it works always when I click at checkbox and filter button instead only filter button.
I tried NgOnChanges but it worked only once and then it didn't see any changes of values into array.
This is my SingleItemsComponent (I think you don't need others to help me solve this). Look at this and show me any example of solving this problem please.
import { Component, OnInit, OnChanges,ViewChild, AfterViewInit, Inject, Input, DoCheck, KeyValueDiffer, KeyValueDiffers, SimpleChanges, SimpleChange, ChangeDetectionStrategy, ChangeDetectorRef, IterableDiffers } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { MatTableDataSource, MatPaginator, MatSort, throwToolbarMixedModesError } from '@angular/material';
import { IPOLine } from 'src/app/models/po-line';
import { POLineService } from 'src/app/services/po-line.service';
@Component({
selector: 'app-po-lines-list',
templateUrl: './po-lines-list.component.html',
styleUrls: ['./po-lines-list.component.css'],
animations: [
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0', display: 'none' })),
state('expanded', style({ height: '*' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
]),
],
})
export class POLinesListComponent implements OnInit, DoCheck{
isLogged = false;
login: string;
dataSource = new MatTableDataSource<IPOLine>();
expandedElement: IPOLine;
errorMessage: string;
response: any;
today = new Date(); // (1990, 0, 1);
isLoadingList = true;
differ: any;
@Input() sentData: boolean;
_sentData = this.sentData;
ngDoCheck(){
var changes = this.differ.diff(this._sentData);
if (changes){
console.log('changes detected changes detected changes detected changes detected changes detected ');
}
else
console.log('changes not detected changes not detected changes not detected changes not detected ');
}
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(
//private cd: ChangeDetectorRef,
private differs: KeyValueDiffers,
private _POLineService: POLineService,
private activatedRoute: ActivatedRoute) {
this.differ = differs.find({}).create();
}
ngOnInit() {
// Assign the data to the data source for the table to render
this.login = this.activatedRoute.snapshot.paramMap.get('login');
this._POLineService.getUserPOLines(this.login)
.subscribe(data => {
this.dataSource.data = data;
},
error => {
this.errorMessage = <any>error;
this.isLoadingList = false;
}
,
() => {
// console.log('eee' + this.dataSource.data);
this.isLoadingList = false;
this.dataSource.data.forEach(x => x.isExpired = new Date(x.PromisedDate) < new Date() ? true : false);
}
);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
}
I'm sorry for the mess in a code but I tried so many things i don't even remember what was what. Thanks for any help.
FilterComponent.ts:
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
@Component({
selector: 'app-filters',
templateUrl: './filters.component.html',
styleUrls: ['./filters.component.css']
})
export class FiltersComponent implements OnInit {
@Output() filterByClass = new EventEmitter();
filterByTTR = false;
filterByTBR = false;
filters:boolean = ;
constructor() { }
ngOnInit() {
}
log() {
if(!this.filterByTTR)
console.log('TTR not checked');
else
console.log('TTR checked');
if (!this.filterByTBR)
console.log('TBR not checked');
else
console.log('TBR checked');
this.filters[0] = this.filterByTTR;
this.filters[1] = this.filterByTBR;
this.filterByClass.emit(this.filters);
}
Part of FilterComponent.html:
<mat-card-content class="col">
<mat-checkbox [checked]="filterByTTR" (change)="filterByTTR = !filterByTTR">TTR</mat-checkbox>
<mat-checkbox [checked]="filterByTBR" (change)="filterByTBR = !filterByTBR">TBR</mat-checkbox>
<!-- <mat-checkbox [(ngModel)]="filterByTBR"ref-TBR>TBR</mat-checkbox> -->
<div class="d-flex justify-content-between">
<button mat-raised-button color="primary">Clear</button>
<button mat-raised-button (click)="log()" color="primary">Apply</button>
</div>
PoLinesCompoenent.ts:
import { Component, OnInit, NgModule, ViewChild, Input } from
'@angular/core';
@Component({
selector: 'app-po-lines',
templateUrl: './po-lines.component.html',
styleUrls: ['./po-lines.component.css']
})
export class POLinesComponent implements OnInit {
count: boolean;
constructor() { }
ngOnInit(){}
displayCounter(count) {
console.log('first value is: ' + count[0] + ' second value is: ' + count[1]);
this.count = count;
}
PoLinesComponent.html:
<div class="container">
<div class="row">
<div class="side-bar col">
<app-filters (data)='displayCounter($event)'></app-filters>
</div>
<div class="content col">
<app-po-lines-list [sentData]="count"></app-po-lines-list>
</div>
</div>
</div>
angular ngoninit ngonchanges
angular ngoninit ngonchanges
edited Nov 14 '18 at 13:43
Mystax
asked Nov 14 '18 at 11:52
MystaxMystax
32
32
Do you want to detect change when@Input() sentData: boolean;
from the outside changes?
– Nabil Shahid
Nov 14 '18 at 12:06
Exactly, I'm trying to detect changes in the other component. Do you know what's wrong here?
– Mystax
Nov 14 '18 at 12:10
Ok so basically you want to perform some action in the POLinesListComponent whensentData
is changed via a parent component right?
– Nabil Shahid
Nov 14 '18 at 12:14
That's it, I select checkboxes, click filter button, and then array with their states goes to PoLinesComponent which is a parent component of PoLinesListComponent and FilterComponent.
– Mystax
Nov 14 '18 at 12:19
Got it. See my answer
– Nabil Shahid
Nov 14 '18 at 12:34
|
show 3 more comments
Do you want to detect change when@Input() sentData: boolean;
from the outside changes?
– Nabil Shahid
Nov 14 '18 at 12:06
Exactly, I'm trying to detect changes in the other component. Do you know what's wrong here?
– Mystax
Nov 14 '18 at 12:10
Ok so basically you want to perform some action in the POLinesListComponent whensentData
is changed via a parent component right?
– Nabil Shahid
Nov 14 '18 at 12:14
That's it, I select checkboxes, click filter button, and then array with their states goes to PoLinesComponent which is a parent component of PoLinesListComponent and FilterComponent.
– Mystax
Nov 14 '18 at 12:19
Got it. See my answer
– Nabil Shahid
Nov 14 '18 at 12:34
Do you want to detect change when
@Input() sentData: boolean;
from the outside changes?– Nabil Shahid
Nov 14 '18 at 12:06
Do you want to detect change when
@Input() sentData: boolean;
from the outside changes?– Nabil Shahid
Nov 14 '18 at 12:06
Exactly, I'm trying to detect changes in the other component. Do you know what's wrong here?
– Mystax
Nov 14 '18 at 12:10
Exactly, I'm trying to detect changes in the other component. Do you know what's wrong here?
– Mystax
Nov 14 '18 at 12:10
Ok so basically you want to perform some action in the POLinesListComponent when
sentData
is changed via a parent component right?– Nabil Shahid
Nov 14 '18 at 12:14
Ok so basically you want to perform some action in the POLinesListComponent when
sentData
is changed via a parent component right?– Nabil Shahid
Nov 14 '18 at 12:14
That's it, I select checkboxes, click filter button, and then array with their states goes to PoLinesComponent which is a parent component of PoLinesListComponent and FilterComponent.
– Mystax
Nov 14 '18 at 12:19
That's it, I select checkboxes, click filter button, and then array with their states goes to PoLinesComponent which is a parent component of PoLinesListComponent and FilterComponent.
– Mystax
Nov 14 '18 at 12:19
Got it. See my answer
– Nabil Shahid
Nov 14 '18 at 12:34
Got it. See my answer
– Nabil Shahid
Nov 14 '18 at 12:34
|
show 3 more comments
2 Answers
2
active
oldest
votes
You can use the setter with input to detect the changes if 'sentData` input is changed by the parent. The setter function will be called everytime the input changes from outside. For example you can do something like:
@Input('sentData')
set sentData(value:any){
//this function will be called whenever value of input changes. the value parameter will contain the new changed
this._sentData=value;
//things to perform on change go here
}
_sentData;
See this link for more details about input change detection : Intercept @Input property change in Angular
Hope this helps.
If the value passed in input via parent is not a primitive type then angular wont detect the changes in that object and the setter wont be called in the child i.e. POLinesListComponent
. For fixing this issue and getting your change detected, you can use Object.assign
function of javascript which will change the reference of this.count
thus triggering angular change detection.
You can do something like the following in your displayCounter
function:
displayCounter(count) {
console.log('first value is: ' + count[0] + ' second value is: ' + count[1]);
//if count is changed, then only trigger change.
if(JSON.stringify(this.count)!=JSON.stringify(count))
{
this.count= ;
Object.assign(this.count, count);
}
}
I have even created a stackblitz similar to your implementation in which the change is being detected properly and the value of new count is being logged to the console everytime filter is applied. Here Input Change Detection for Object
It's something similar i have done before and it behaves exactly the same. I followed your instructions, and added console.log to see if it reaches setter each time I filter. Unfortunately it sees changes only once at the first time.
– Mystax
Nov 14 '18 at 13:00
How is the value being changed in the parent component? Is it two way binded to a control or you change it manually in a function?
– Nabil Shahid
Nov 14 '18 at 13:23
In a moment I will edit my question and I add other components code.
– Mystax
Nov 14 '18 at 13:34
add a comment |
Angular change detection only checks if something changed by reference. In your parent component, you have to create a new array and assign it to the variable everytime a change occurs to your entries inside your array. Just think of arrays as Immutables.
I reed about Immutables, and i know it's not the best solution when there is big object to recreate, that means there must be another way to do this. Indeed I will try do that with them because this array isn't gonna be big.
– Mystax
Nov 14 '18 at 12:16
There is no other way to do that. It would be way slower to check if any elements in an array changed than to just recreate it. What you could do to bypass this if performance is an issue is scheduling the change detector yourself - change the array as mucb as you want, recreate it once and then use ChangeDetectorRef to mark the component for check. Additionally, the overhead for recreating an array is usually not much.
– pascalpuetz
Nov 14 '18 at 12:19
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53299640%2fangular-array-changes-detection%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can use the setter with input to detect the changes if 'sentData` input is changed by the parent. The setter function will be called everytime the input changes from outside. For example you can do something like:
@Input('sentData')
set sentData(value:any){
//this function will be called whenever value of input changes. the value parameter will contain the new changed
this._sentData=value;
//things to perform on change go here
}
_sentData;
See this link for more details about input change detection : Intercept @Input property change in Angular
Hope this helps.
If the value passed in input via parent is not a primitive type then angular wont detect the changes in that object and the setter wont be called in the child i.e. POLinesListComponent
. For fixing this issue and getting your change detected, you can use Object.assign
function of javascript which will change the reference of this.count
thus triggering angular change detection.
You can do something like the following in your displayCounter
function:
displayCounter(count) {
console.log('first value is: ' + count[0] + ' second value is: ' + count[1]);
//if count is changed, then only trigger change.
if(JSON.stringify(this.count)!=JSON.stringify(count))
{
this.count= ;
Object.assign(this.count, count);
}
}
I have even created a stackblitz similar to your implementation in which the change is being detected properly and the value of new count is being logged to the console everytime filter is applied. Here Input Change Detection for Object
It's something similar i have done before and it behaves exactly the same. I followed your instructions, and added console.log to see if it reaches setter each time I filter. Unfortunately it sees changes only once at the first time.
– Mystax
Nov 14 '18 at 13:00
How is the value being changed in the parent component? Is it two way binded to a control or you change it manually in a function?
– Nabil Shahid
Nov 14 '18 at 13:23
In a moment I will edit my question and I add other components code.
– Mystax
Nov 14 '18 at 13:34
add a comment |
You can use the setter with input to detect the changes if 'sentData` input is changed by the parent. The setter function will be called everytime the input changes from outside. For example you can do something like:
@Input('sentData')
set sentData(value:any){
//this function will be called whenever value of input changes. the value parameter will contain the new changed
this._sentData=value;
//things to perform on change go here
}
_sentData;
See this link for more details about input change detection : Intercept @Input property change in Angular
Hope this helps.
If the value passed in input via parent is not a primitive type then angular wont detect the changes in that object and the setter wont be called in the child i.e. POLinesListComponent
. For fixing this issue and getting your change detected, you can use Object.assign
function of javascript which will change the reference of this.count
thus triggering angular change detection.
You can do something like the following in your displayCounter
function:
displayCounter(count) {
console.log('first value is: ' + count[0] + ' second value is: ' + count[1]);
//if count is changed, then only trigger change.
if(JSON.stringify(this.count)!=JSON.stringify(count))
{
this.count= ;
Object.assign(this.count, count);
}
}
I have even created a stackblitz similar to your implementation in which the change is being detected properly and the value of new count is being logged to the console everytime filter is applied. Here Input Change Detection for Object
It's something similar i have done before and it behaves exactly the same. I followed your instructions, and added console.log to see if it reaches setter each time I filter. Unfortunately it sees changes only once at the first time.
– Mystax
Nov 14 '18 at 13:00
How is the value being changed in the parent component? Is it two way binded to a control or you change it manually in a function?
– Nabil Shahid
Nov 14 '18 at 13:23
In a moment I will edit my question and I add other components code.
– Mystax
Nov 14 '18 at 13:34
add a comment |
You can use the setter with input to detect the changes if 'sentData` input is changed by the parent. The setter function will be called everytime the input changes from outside. For example you can do something like:
@Input('sentData')
set sentData(value:any){
//this function will be called whenever value of input changes. the value parameter will contain the new changed
this._sentData=value;
//things to perform on change go here
}
_sentData;
See this link for more details about input change detection : Intercept @Input property change in Angular
Hope this helps.
If the value passed in input via parent is not a primitive type then angular wont detect the changes in that object and the setter wont be called in the child i.e. POLinesListComponent
. For fixing this issue and getting your change detected, you can use Object.assign
function of javascript which will change the reference of this.count
thus triggering angular change detection.
You can do something like the following in your displayCounter
function:
displayCounter(count) {
console.log('first value is: ' + count[0] + ' second value is: ' + count[1]);
//if count is changed, then only trigger change.
if(JSON.stringify(this.count)!=JSON.stringify(count))
{
this.count= ;
Object.assign(this.count, count);
}
}
I have even created a stackblitz similar to your implementation in which the change is being detected properly and the value of new count is being logged to the console everytime filter is applied. Here Input Change Detection for Object
You can use the setter with input to detect the changes if 'sentData` input is changed by the parent. The setter function will be called everytime the input changes from outside. For example you can do something like:
@Input('sentData')
set sentData(value:any){
//this function will be called whenever value of input changes. the value parameter will contain the new changed
this._sentData=value;
//things to perform on change go here
}
_sentData;
See this link for more details about input change detection : Intercept @Input property change in Angular
Hope this helps.
If the value passed in input via parent is not a primitive type then angular wont detect the changes in that object and the setter wont be called in the child i.e. POLinesListComponent
. For fixing this issue and getting your change detected, you can use Object.assign
function of javascript which will change the reference of this.count
thus triggering angular change detection.
You can do something like the following in your displayCounter
function:
displayCounter(count) {
console.log('first value is: ' + count[0] + ' second value is: ' + count[1]);
//if count is changed, then only trigger change.
if(JSON.stringify(this.count)!=JSON.stringify(count))
{
this.count= ;
Object.assign(this.count, count);
}
}
I have even created a stackblitz similar to your implementation in which the change is being detected properly and the value of new count is being logged to the console everytime filter is applied. Here Input Change Detection for Object
edited Nov 15 '18 at 9:49
answered Nov 14 '18 at 12:34
Nabil ShahidNabil Shahid
67826
67826
It's something similar i have done before and it behaves exactly the same. I followed your instructions, and added console.log to see if it reaches setter each time I filter. Unfortunately it sees changes only once at the first time.
– Mystax
Nov 14 '18 at 13:00
How is the value being changed in the parent component? Is it two way binded to a control or you change it manually in a function?
– Nabil Shahid
Nov 14 '18 at 13:23
In a moment I will edit my question and I add other components code.
– Mystax
Nov 14 '18 at 13:34
add a comment |
It's something similar i have done before and it behaves exactly the same. I followed your instructions, and added console.log to see if it reaches setter each time I filter. Unfortunately it sees changes only once at the first time.
– Mystax
Nov 14 '18 at 13:00
How is the value being changed in the parent component? Is it two way binded to a control or you change it manually in a function?
– Nabil Shahid
Nov 14 '18 at 13:23
In a moment I will edit my question and I add other components code.
– Mystax
Nov 14 '18 at 13:34
It's something similar i have done before and it behaves exactly the same. I followed your instructions, and added console.log to see if it reaches setter each time I filter. Unfortunately it sees changes only once at the first time.
– Mystax
Nov 14 '18 at 13:00
It's something similar i have done before and it behaves exactly the same. I followed your instructions, and added console.log to see if it reaches setter each time I filter. Unfortunately it sees changes only once at the first time.
– Mystax
Nov 14 '18 at 13:00
How is the value being changed in the parent component? Is it two way binded to a control or you change it manually in a function?
– Nabil Shahid
Nov 14 '18 at 13:23
How is the value being changed in the parent component? Is it two way binded to a control or you change it manually in a function?
– Nabil Shahid
Nov 14 '18 at 13:23
In a moment I will edit my question and I add other components code.
– Mystax
Nov 14 '18 at 13:34
In a moment I will edit my question and I add other components code.
– Mystax
Nov 14 '18 at 13:34
add a comment |
Angular change detection only checks if something changed by reference. In your parent component, you have to create a new array and assign it to the variable everytime a change occurs to your entries inside your array. Just think of arrays as Immutables.
I reed about Immutables, and i know it's not the best solution when there is big object to recreate, that means there must be another way to do this. Indeed I will try do that with them because this array isn't gonna be big.
– Mystax
Nov 14 '18 at 12:16
There is no other way to do that. It would be way slower to check if any elements in an array changed than to just recreate it. What you could do to bypass this if performance is an issue is scheduling the change detector yourself - change the array as mucb as you want, recreate it once and then use ChangeDetectorRef to mark the component for check. Additionally, the overhead for recreating an array is usually not much.
– pascalpuetz
Nov 14 '18 at 12:19
add a comment |
Angular change detection only checks if something changed by reference. In your parent component, you have to create a new array and assign it to the variable everytime a change occurs to your entries inside your array. Just think of arrays as Immutables.
I reed about Immutables, and i know it's not the best solution when there is big object to recreate, that means there must be another way to do this. Indeed I will try do that with them because this array isn't gonna be big.
– Mystax
Nov 14 '18 at 12:16
There is no other way to do that. It would be way slower to check if any elements in an array changed than to just recreate it. What you could do to bypass this if performance is an issue is scheduling the change detector yourself - change the array as mucb as you want, recreate it once and then use ChangeDetectorRef to mark the component for check. Additionally, the overhead for recreating an array is usually not much.
– pascalpuetz
Nov 14 '18 at 12:19
add a comment |
Angular change detection only checks if something changed by reference. In your parent component, you have to create a new array and assign it to the variable everytime a change occurs to your entries inside your array. Just think of arrays as Immutables.
Angular change detection only checks if something changed by reference. In your parent component, you have to create a new array and assign it to the variable everytime a change occurs to your entries inside your array. Just think of arrays as Immutables.
answered Nov 14 '18 at 12:12
pascalpuetzpascalpuetz
37619
37619
I reed about Immutables, and i know it's not the best solution when there is big object to recreate, that means there must be another way to do this. Indeed I will try do that with them because this array isn't gonna be big.
– Mystax
Nov 14 '18 at 12:16
There is no other way to do that. It would be way slower to check if any elements in an array changed than to just recreate it. What you could do to bypass this if performance is an issue is scheduling the change detector yourself - change the array as mucb as you want, recreate it once and then use ChangeDetectorRef to mark the component for check. Additionally, the overhead for recreating an array is usually not much.
– pascalpuetz
Nov 14 '18 at 12:19
add a comment |
I reed about Immutables, and i know it's not the best solution when there is big object to recreate, that means there must be another way to do this. Indeed I will try do that with them because this array isn't gonna be big.
– Mystax
Nov 14 '18 at 12:16
There is no other way to do that. It would be way slower to check if any elements in an array changed than to just recreate it. What you could do to bypass this if performance is an issue is scheduling the change detector yourself - change the array as mucb as you want, recreate it once and then use ChangeDetectorRef to mark the component for check. Additionally, the overhead for recreating an array is usually not much.
– pascalpuetz
Nov 14 '18 at 12:19
I reed about Immutables, and i know it's not the best solution when there is big object to recreate, that means there must be another way to do this. Indeed I will try do that with them because this array isn't gonna be big.
– Mystax
Nov 14 '18 at 12:16
I reed about Immutables, and i know it's not the best solution when there is big object to recreate, that means there must be another way to do this. Indeed I will try do that with them because this array isn't gonna be big.
– Mystax
Nov 14 '18 at 12:16
There is no other way to do that. It would be way slower to check if any elements in an array changed than to just recreate it. What you could do to bypass this if performance is an issue is scheduling the change detector yourself - change the array as mucb as you want, recreate it once and then use ChangeDetectorRef to mark the component for check. Additionally, the overhead for recreating an array is usually not much.
– pascalpuetz
Nov 14 '18 at 12:19
There is no other way to do that. It would be way slower to check if any elements in an array changed than to just recreate it. What you could do to bypass this if performance is an issue is scheduling the change detector yourself - change the array as mucb as you want, recreate it once and then use ChangeDetectorRef to mark the component for check. Additionally, the overhead for recreating an array is usually not much.
– pascalpuetz
Nov 14 '18 at 12:19
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53299640%2fangular-array-changes-detection%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Do you want to detect change when
@Input() sentData: boolean;
from the outside changes?– Nabil Shahid
Nov 14 '18 at 12:06
Exactly, I'm trying to detect changes in the other component. Do you know what's wrong here?
– Mystax
Nov 14 '18 at 12:10
Ok so basically you want to perform some action in the POLinesListComponent when
sentData
is changed via a parent component right?– Nabil Shahid
Nov 14 '18 at 12:14
That's it, I select checkboxes, click filter button, and then array with their states goes to PoLinesComponent which is a parent component of PoLinesListComponent and FilterComponent.
– Mystax
Nov 14 '18 at 12:19
Got it. See my answer
– Nabil Shahid
Nov 14 '18 at 12:34