Reputation: 3311
We have a simple component with an input property as such:
<app-example [exampleInput$]="exampleInputData$"></app-example>
On the component where we use app-example
we have:
get exampleInputData$(): any {
var subject = new Subject<string>();
console.log("Log1");
this.exampleService.getAllData(this.id).subscribe(data => {
console.log("Log2");
subject.next(data);
});
return subject.asObservable();
}
And the exampleService
is a simple observable as such:
public getAllData(id): Observable<ExampleObject[]> {
return this.http.get(`${this.baseUrl}data/${id}`).map((response: Response) => {
var data = <ExampleObject[]>response.json();
return data;
}).catch(this.handleError);
}
When we run this it get's into an infinite loop, if we change the changeDetection
to OnPush
it stops or if we remove the call to getAllData
. Does anyone have an idea of why this is causing an infinite loop?
Below is the app-example
component and the HTML template:
export class ExampleComponent implements OnDestroy {
private subscription: ISubscription;
private parsedResponse : any;
@Input() exampleInput$;
getData(): void
{
this.subscription = this.exampleInput$.subscribe((data) => {this.parsedResponse = data;},
() => {
// Here we download the data as CSV
});
}
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
Template:
<button class="btn btn-primary" (click)="getData()">
Download As CSV
</button>
Upvotes: 4
Views: 5829
Reputation: 1325
You are binding a method in the HTML. So in every change detection the method will be invoked. You need to set the observable like an attribute and the content in the exampleInputData$() put it in ngOnInit
export AppComponent {
subject = new Subject<string>();
observable$ = subject.asObservable();
id: number;
ngOnInit() {
// I expected you know how to get the id value
this.exampleService.getAllData(this.id).subscribe(data => {
this.subject.next(data);
});
}
}
And the HTML
<app-example [exampleInput$]="observable$"></app-example>
Upvotes: 2
Reputation: 6794
I don't know how the rest of your code goes, but I think you may be calling exampleInputData$ in each render, you should do something like this:
Class Component implements OnInit {
constructor(exampleInputDataService: ExampleInputDataService) {
}
ngOnInit(): void {
this.data = this.exampleInputDataService.getData();
}
}
Upvotes: 0