So i have this Component of a from with an @Output
event that trigger on submit, as follows:
@Component({
selector: 'some-component',
templateUrl: './SomeComponent.html'
})
export class SomeComponent{
@Input() data: any;
@Output() onSubmit: EventEmitter<void> = new EventEmitter<void>();
constructor(private someService: SomeService) {}
submitForm(): void{
this.someService.updateBackend(this.data, ()=>{
this.onSubmit.emit();
});
}
}
I'm using an ngFor
to create multiple elements of this Component :
<template let-data ngFor [ngForOf]="dataCollection">
<some-component [data]="data" (onSubmit)="doSomthing()"></some-component>
</template>
The last missing part is the service used on submitting:
@Injectable()
export class SomeService{
constructor() {}
updateBackend(data: any, callback: () => void): void{
/*
* updating the backend
*/.then((result) => {
const { errors, data } = result;
if (data) {
callback();
}
})
}
}
At the beginning of the submitForm()
function, the this.onSubmit.observers
is an Array containing one observer, like it should be.
As soon as it reaches the callback method, where the this.onSubmit.emit()
is invoked, the this.onSubmit.observers
is an Array containing ZERO observers.
SomeService.updateBackend
it works perfectly fine, and the observers
still is an Array containing one observer!ngFor
and displaying only one <some-element>
it also works perfectly fine, keeping one observer in the this.onSubmit.observers
within the callback scope!Any idea what am i doing wrong?
Thanks in advance!
Thanks to @StevenLuke's comment about logging the ngOnDestroy
of SomeComponent
I found out that it is being destroyed before the emit.
Actually, the first thing it is doing when the SomeService.updateBackend
finishes is Destroying all the instances of this component and recreate them!
This is what makes the observers change! Why would that happen?
If you provide a trackBy function in your *ngFor to identify items in your dataCollection, it will not destroy and init. Your template would be:
<some-component *ngFor="let data of dataCollection;trackBy:trackByFunction"
[data]="data" (onSubmit)="doSomthing()"></some-component>
And the trackByFunction would look like:
trackByFunction(index, item) {
return item ? item.id : undefined;
}
So even though an item in your dataCollection is a fresh object, if its id matches an id in the previous collection, *ngFor will update [data] but not destroy and init the component.
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