Reputation: 912
I have one component(bootstrap modal), where I edit some info. Then I send it using service. It looks like this
this.service.updateCompanyById(companyInfo, this.company.id, this.logoImage)
.subscribe(
(data) => {
this.bsModalRef.hide();
},
(err) => console.log(err)
);
In my service
updateCompanyById(company, companyId, logoImage?: File) {
... some code
return
this.http.post(`${this.domainName}api/companies/update/${companyId}`, formData)
.do(
(data) => {
this.companyUpdated.next()
this.notificationService.notify('Company updated successfully!');
}
);
}
As you see I use Subject, so another component knows that company was updated. That component just contains list of all companies, which it gets using service. In this component I have
// list of companies
this.companiesService.companyUpdated
.subscribe(
() => {
this.getCompaniesFromServer();
}
)
getCompaniesFromServer() {
this.companiesService.getCompaniesInfo()
.pipe(
share()
)
.subscribe(
(data) => {
this.rows = data;
console.log(data);
}
);
}
The problem I have is that all requests getting duplicated.
For example: I edit user for the first time and get one response with list of all users in my list of companies component. Then after editing it second time, I get two responses and so on. I assume the problem is with Subject but I can't understand what exactly is wrong. Please help me if you can, thanks in advance
Can anybody explain why does it happen and what is the reason for such behavior? Possible solution proposed by @misha130 is to add .pipe(first()) Another possible soultion (though I am not sure in it) is to add .pipe(take(1))
Upvotes: 1
Views: 131
Reputation: 912
So, I looked at this problem once more, and realized what was the problem and what the possible solution is. I am still not sure if I got it right though.
First of all, I had two subscriptions to one subject I had it in one function
onEditCompany(){
this.companiesService.companyUpdated
.subscribe(
(data) => {
console.log(data);
this.getCompaniesFromServer();
}
);
}
And then in another function
onCreateCompany() {
this.companiesService.companyUpdated
.subscribe(
(data) => {
console.log(data);
this.getCompaniesFromServer();
}
);
}
As far as I got it this created two subscriptions in one place, that's why I had multiple requests instead of one. So as far as I realized, that I need only one instance of companyUpdated, and as far as it will be received either from update company in service or from add company in that service I assume that I need just to move my this.companiesService.companyUpdated to ngOnInit, so it will listen to changes for both add new company and update company cases. So, now it looks like this: Remove old code from both onEditCompany() and onCreateCompany() and write the following in ngOnInit:
this.companyUpdatedSubscription = this.companiesService.companyUpdated
.switchMap(
() => this.companiesService.getCompaniesInfo()
)
.subscribe(
(data) => this.rows = data
);
Upvotes: 1
Reputation: 5706
Either add first() before the subscribe to signify that its only going to take the value once or dispose of the subscription after receiving it.
The issue here is not that the subscription gets twice the data but that there are two subscriptions. Option A:
this.companiesService.companyUpdated
first().subscribe(
() => {
this.getCompaniesFromServer();
}
)
Option B:
let companyUpdateSubscription: Subscription = this.companiesService.companyUpdated
first().subscribe(
() => {
this.getCompaniesFromServer();
companyUpdateSubscription.unsubscribe();
}
)
On a note: If you choose option A I would still do unsubscribe onDestroy for the sake of memory management.
Upvotes: 1