Reputation: 105
I have 2 Array<object>
. One of them has initial elements and another one has its elements added by array.push()
in ngOnInit
. In the end, both have the elements in output but html doesn't render the elements which were pushed with .push
//the result of array that made by array.push
> []
> 0: {id: '1', title: 'title 1'}
> 1: {id: '2', title: 'title 2'}
> 2: {id: '3', title: 'title 3'}
length: 3
> __proto__: Array(0)
//initialize array
> (3) [{…}, {…}, {…}]
> 0: {id: '1', title: 'title 1'}
> 1: {id: '2', title: 'title 2'}
> 2: {id: '3', title: 'title 3'}
length: 3
> __proto__: Array(0)
the code
newObj;
error;
myObjects: Array<object> = [];
itsObjects: Array<object> = [
{
id: '1',
title: 'title 1'
},
{
id: '2',
title: 'title 2'
},
{
id: '3',
title: 'title 3'
}
];
ngOnInit() {
this.subscription = this.mys.myService().subscribe(
res => {
this.newObj = res,
this.myObjects.push(
{
id: element.id,
title: element.title
}
)
},
error => this.error = error,
)
}
Solved
The main notice was this.myObjects = this.tmpObj
after forEach
that collects all elements for pass to out of ngOnInit
scope, I edited my code to:
servicOutput; //get data
tmpObj: Array<object> = []; //manage data as temp;
myObjects: Array<object> = []; //for collect all elements to html
error;
ngOnInit() {
this.subscription = this.mys.myService().subscribe(
res => {
this.servicOutput = res,
this.servicOutput.forEach(element => {
this.pushFunc(element);
}
),
this.myObjects = this.tmpObj; //here collect all elements as an object and pass out of ngOnInit scope
},
error => this.error = error,
)
}
pushFunc(element) {
this.tmpObj.push(
{
id: element.id,
title: element.title
}
)
}
Upvotes: 4
Views: 4223
Reputation: 2756
Angular doesn't detect changes within an array. It only detects when the reference to the array itself changes. To get the html to re-render you need to use one of the following methods which will alert Angular that something has changed.
Kudos to Rushi Patel for this method.
this.myObjects = [...this.myObjects, this.newObj[0]];
this.myObjects.push(this.newObj[0]);
this.myObjects = [...this.myObjects];
this.myObjects.push(this.newObj[0]);
this.myObjects = JSON.parse(JSON.stringify(this.myObjects));
This is also suggested in https://stackoverflow.com/a/57689299/470014
constructor(private changeDetectorRef: ChangeDetectorRef) { }
public testMethod() {
this.myObjects.push(this.newObj[0]);
this.changeDetectorRef.detectChanges();}
Upvotes: 2
Reputation: 48
assuming your service return any value, you can call detectchanges method after each arr.push(), because angular does not recognize changes like push / pop automatically. Like so:
constructor(private changeDetectorRef: ChangeDetectorRef) { }
public testMethod() {
this.arr.push({name: 'test'});
this.changeDetectorRef.detectChanges();
}
Upvotes: 0
Reputation: 71
if in this.tmpObj
you get all data and the problem is when you try to assign this data to this.myObjects
then use slice method from arrays this.myObjects = this.tmpObj.slice()
Upvotes: 0
Reputation: 2165
Angular's change detection mechanism does not handle the content change of an array. You can either change the referance of the array as xdecdec suggested earlier in comments or you can implement your own ngDoChange so that you can implement your own way to detect the change of array content.
Check this answer for further explanation on implementing ngDoChange: https://stackoverflow.com/a/42962723/11420760
Upvotes: 2