There is strange issue I'm encountering at first I try to submit form it succeeds without any issue here is an code excerpt below from page.
userRole.ts:
ngOnInit() {
const userSubscription = this.userManagementService.currentUsersIdValue.pipe(
switchMap((userId: string) => {
if (userId.length > 0) {
return this.userManagementService.getUsers(userId.toString());
}
else {
return this.userDetailsArr;
}
}
)).subscribe((users) => {
if (users !== null) {
const sbCreate = this.userManagementService.getUsersRole(users[0].id)
.subscribe((roles: any) => {
if (roles.length > 0) {
this.userRoleList = roles;
this.ref.detectChanges();
}
});
this.subscriptions.push(sbCreate);
}
});
this.subscriptions.push(userSubscription);
}
//// This is the process to submit form data
onSubmitRole() {
if (this.userRole.commonForm.invalid) {
alert('Please fill the form');
return;
}
const roleData = this.userRole.commonForm.value;
////This runs first time when I route to this page after re-routing to this page it starts again without clicking button
const userSubscribe = this.userManagementService.currentUsersIdValue.pipe(
switchMap((userId: string) => {
if (userId.length > 0) {
return this.userManagementService.getUsers(userId.toString());
}
else {
return this.userDetailsArr;
}
}
)).subscribe((users) => {
if (users !== null) {
this.authService.currentUserValue.forEach(u => {
if (roleData.RoleID) {
roleData.CompanyID = roleData.CompanyID;
roleData.CreatedBy = roleData.CreatedBy;
roleData.CreatedDate = roleData.CreatedDate;
roleData.LastModifiedDate = new Date().toLocaleString();
roleData.DefaultRoleID = '00000000-0000-0000-0000-000000000000';
}
else {
roleData.RoleID = '00000000-0000-0000-0000-000000000000';
roleData.CompanyID = u.companyID;
roleData.CreatedBy = u.id;
roleData.CreatedDate = new Date().toLocaleString();
roleData.LastModifiedBy = u.id;
roleData.LastModifiedDate = new Date().toLocaleString();
roleData.Internal = true;
roleData.RoleTypeCode = 1;
roleData.DefaultRoleID = '00000000-0000-0000-0000-000000000000';
}
const sbCreate = this.userManagementService.upsertUserRole(roleData)
.subscribe((response: any) => {
if (response.Status === 200) {
this.router.navigate(['general-management/viewprofile']);
}
else {
alert(response.Description);
}
});
this.subscriptions.push(sbCreate);
});
}
else {
if (confirm('Please edit/add any user to continue with Role!')) {
this.router.navigate(['general-management/viewprofile']);
}
}
});
this.subscriptions.push(userSubscribe);
}
Now the problem is that at initial of the page userRole.ts when I hit submit to call this method onSubmitRole() it delivers the data to service and then to server, which is OK after success it routes back to mainUser.ts page when I edit a certain list
from the main page to reach userRole.ts page then the strange phenomenon happens, it starts this const userSubscribe = this.userManagementService.currentUsersIdValue.pipe
from onSubmitRole()
this BehaviourSubject will initially start first time but after edit second time back to this page it will automatically start again const userSubscribe = this.userManagementService.currentUsersIdValue.pipe
without hitting onSubmitRole().
The process is as follow - mainUser.ts (have list which can be edited to route to next page) --> userRole.ts (which has a form submit button and here is the strange issue is happening) automatically it runs the service second time on edit.
Here is the userRole.Html page
<div *ngIf="!showRolesTable">
<form [formGroup]="userRole.commonForm" (ngSubmit)="onSubmitRole()">
<div >
<label for="RoleName">Role Name</label>
<input type="hidden" [(ngModel)]="userRole.RoleID" formControlName="RoleID">
<input type="text" [(ngModel)]="userRole.RoleName" formControlName="RoleName" id="RoleName" placeholder="Enter Role Name">
</div>
<div >
<label for="Description">Description</label>
<input type="text" [(ngModel)]="userRole.Description" formControlName="Description"
id="Description" placeholder="Enter Description">
</div>
<button type="submit" >Submit</button>
</form>
</div>
CodePudding user response:
There's no magic in JS - if no one is calling onSubmitRole()
(you put in a debugger statement and it doesn't trigger), then it means that the previous subscription is still active.
When you do const userSubscribe = this.userManagementService.currentUsersIdValue.pipe(...).subscribe(...)
you are creating a subscription which will keep listening for changes in currentUsersIdValue
. The only possibility is that when you go to userRole
page the second time, that observable emits something and causes the previous instance of userRole
to trigger whatever that pipe triggers.
As for solutions... 1) Make sure that you're cleaning out the subscriptions when the user leaves the userRole
page, that could actually be a leak. 2) add a take(1)
operator at the very beginning of the pipe: This operator will automatically unsubscribe once 1 value has been received.
CodePudding user response:
Be sure to unsubscribe
from your subscription. Implement OnDestroy()
interface in your component then call the subscription.unsubscribe()
. Additionally, If you do not need the previous value in your Observable
then it is better to use Subject()
not BehaviourSubject()
. Read more on the different types of Subjects in RxJs