admin管理员组文章数量:1287973
I have one angular component a I want to simplify this Rx.js functions to have one only one subscribe and not have subscrition in subsribe. Is it possible? Otherwise this Rx.js has task debounce form values whenever they change and send to server values to check if app password is valid, if it is, toastr and modal close is called.
import {
ChangeDetectionStrategy,
Component,
OnDestroy,
OnInit,
} from '@angular/core';
import {
FormControl,
FormGroup,
FormsModule,
ReactiveFormsModule,
} from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { FormWrapperComponent } from '@app/components/form-wrapper/form-wrapperponent';
import { EHttpResponseCode } from '@app/enums/http-response';
import { IPasswordForm } from '@app/interfaces/password-form.interface';
import { AppPasswordService } from '@app/services/app-password.service';
import { ModalService } from '@app/services/modal.service';
import { environment } from '@environments/environment';
import { I18NextModule, I18NextPipe } from 'angular-i18next';
import { ToastrService } from 'ngx-toastr';
import { debounceTime, distinctUntilChanged, Subscription } from 'rxjs';
@Component({
selector: 'app-application-password-modal',
imports: [
MatInputModule,
MatFormFieldModule,
I18NextModule,
FormsModule,
ReactiveFormsModule,
FormWrapperComponent,
],
templateUrl: './application-password-modalponent.html',
styleUrl: './application-password-modalponent.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ApplicationPasswordModalComponent implements OnInit, OnDestroy {
/**
* @description
* Property passwordForm is a FormGroup that contains the form to fill up password
* and have access to change database config
*
* @type {FormGroup<IPasswordForm>}
*/
passwordForm: FormGroup<IPasswordForm>;
/**
* Subscription to password values changes
* @type {Subscription}
*/
valuesChangesSubscription: Subscription = new Subscription();
/**
* Subscription to verify password
* @type {Subscription | null}
*/
verifyPasswordSubscription: Subscription | null = null;
/**
* @descriptio
* Constructor
*
* @param {AppPasswordService} appPasswordService
* @param {ModalService} modalService
* @param {ToastrService} toastr
* @param {I18NextPipe} i18nextPipe
*/
constructor(
private appPasswordService: AppPasswordService,
private modalService: ModalService,
private toastr: ToastrService,
private i18nextPipe: I18NextPipe
) {
this.passwordForm = new FormGroup<IPasswordForm>({
password: new FormControl<string | null>('', []),
});
}
/**
* @description
* Lifecycle method
* Update form values from session storage is stored data are present
* and subscribing to form value changes to log form validation from backend
*
* @returns {void}
*/
ngOnInit(): void {
if (!environment.production) {
this.toastr.info(
this.i18nextPipe.transform('In developer mode password is password.')
);
}
/**
* Subscribe to password form value changes
* Debounce logic, 1 second delay
* Distinct until changed form data, only emit if value has changed
* If data are present, data are sended to backend and if data are correct, modal is closed
*/
this.valuesChangesSubscription = this.passwordForm.valueChanges
.pipe(
debounceTime(1000),
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b))
)
.subscribe(() => {
if (this.passwordForm.valid) {
const passwordControl = this.passwordForm.get('password');
const data = {
password: this.passwordForm.value.password ?? '',
};
this.verifyPasswordSubscription = this.appPasswordService
.verifyAppPassword(data)
.subscribe({
next: res => {
if (
res.status === EHttpResponseCode.OK ||
res.status === EHttpResponseCode.CREATED
) {
this.modalService.closeApplicationPasswordModal();
this.toastr.success(
this.i18nextPipe.transform(
'App password is correct. Now You can fill up database config.'
)
);
}
if (res.status === EHttpResponseCode.UNAUTHORIZED) {
passwordControl?.setErrors({ incorrect: true });
this.toastr.error(
this.i18nextPipe.transform(
'App password is incorrect. Please try again.'
)
);
}
},
error: () => {
if (!environment.production) {
if (this.passwordForm.value.password === 'password') {
passwordControl?.setErrors(null);
this.modalService.closeApplicationPasswordModal();
this.toastr.success(
this.i18nextPipe.transform(
'App password is correct. Now You can fill up database config.'
)
);
} else {
passwordControl?.setErrors({ incorrect: true });
this.toastr.error(
this.i18nextPipe.transform(
'App password is incorrect. Please try again.'
)
);
}
}
},
});
}
});
}
ngOnDestroy(): void {
this.verifyPasswordSubscription?.unsubscribe();
this.valuesChangesSubscription?.unsubscribe();
}
}
I have one angular component a I want to simplify this Rx.js functions to have one only one subscribe and not have subscrition in subsribe. Is it possible? Otherwise this Rx.js has task debounce form values whenever they change and send to server values to check if app password is valid, if it is, toastr and modal close is called.
import {
ChangeDetectionStrategy,
Component,
OnDestroy,
OnInit,
} from '@angular/core';
import {
FormControl,
FormGroup,
FormsModule,
ReactiveFormsModule,
} from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { FormWrapperComponent } from '@app/components/form-wrapper/form-wrapperponent';
import { EHttpResponseCode } from '@app/enums/http-response';
import { IPasswordForm } from '@app/interfaces/password-form.interface';
import { AppPasswordService } from '@app/services/app-password.service';
import { ModalService } from '@app/services/modal.service';
import { environment } from '@environments/environment';
import { I18NextModule, I18NextPipe } from 'angular-i18next';
import { ToastrService } from 'ngx-toastr';
import { debounceTime, distinctUntilChanged, Subscription } from 'rxjs';
@Component({
selector: 'app-application-password-modal',
imports: [
MatInputModule,
MatFormFieldModule,
I18NextModule,
FormsModule,
ReactiveFormsModule,
FormWrapperComponent,
],
templateUrl: './application-password-modalponent.html',
styleUrl: './application-password-modalponent.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ApplicationPasswordModalComponent implements OnInit, OnDestroy {
/**
* @description
* Property passwordForm is a FormGroup that contains the form to fill up password
* and have access to change database config
*
* @type {FormGroup<IPasswordForm>}
*/
passwordForm: FormGroup<IPasswordForm>;
/**
* Subscription to password values changes
* @type {Subscription}
*/
valuesChangesSubscription: Subscription = new Subscription();
/**
* Subscription to verify password
* @type {Subscription | null}
*/
verifyPasswordSubscription: Subscription | null = null;
/**
* @descriptio
* Constructor
*
* @param {AppPasswordService} appPasswordService
* @param {ModalService} modalService
* @param {ToastrService} toastr
* @param {I18NextPipe} i18nextPipe
*/
constructor(
private appPasswordService: AppPasswordService,
private modalService: ModalService,
private toastr: ToastrService,
private i18nextPipe: I18NextPipe
) {
this.passwordForm = new FormGroup<IPasswordForm>({
password: new FormControl<string | null>('', []),
});
}
/**
* @description
* Lifecycle method
* Update form values from session storage is stored data are present
* and subscribing to form value changes to log form validation from backend
*
* @returns {void}
*/
ngOnInit(): void {
if (!environment.production) {
this.toastr.info(
this.i18nextPipe.transform('In developer mode password is password.')
);
}
/**
* Subscribe to password form value changes
* Debounce logic, 1 second delay
* Distinct until changed form data, only emit if value has changed
* If data are present, data are sended to backend and if data are correct, modal is closed
*/
this.valuesChangesSubscription = this.passwordForm.valueChanges
.pipe(
debounceTime(1000),
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b))
)
.subscribe(() => {
if (this.passwordForm.valid) {
const passwordControl = this.passwordForm.get('password');
const data = {
password: this.passwordForm.value.password ?? '',
};
this.verifyPasswordSubscription = this.appPasswordService
.verifyAppPassword(data)
.subscribe({
next: res => {
if (
res.status === EHttpResponseCode.OK ||
res.status === EHttpResponseCode.CREATED
) {
this.modalService.closeApplicationPasswordModal();
this.toastr.success(
this.i18nextPipe.transform(
'App password is correct. Now You can fill up database config.'
)
);
}
if (res.status === EHttpResponseCode.UNAUTHORIZED) {
passwordControl?.setErrors({ incorrect: true });
this.toastr.error(
this.i18nextPipe.transform(
'App password is incorrect. Please try again.'
)
);
}
},
error: () => {
if (!environment.production) {
if (this.passwordForm.value.password === 'password') {
passwordControl?.setErrors(null);
this.modalService.closeApplicationPasswordModal();
this.toastr.success(
this.i18nextPipe.transform(
'App password is correct. Now You can fill up database config.'
)
);
} else {
passwordControl?.setErrors({ incorrect: true });
this.toastr.error(
this.i18nextPipe.transform(
'App password is incorrect. Please try again.'
)
);
}
}
},
});
}
});
}
ngOnDestroy(): void {
this.verifyPasswordSubscription?.unsubscribe();
this.valuesChangesSubscription?.unsubscribe();
}
}
Share
Improve this question
edited Mar 3 at 14:05
Orist Timemaker
asked Feb 23 at 17:38
Orist TimemakerOrist Timemaker
771 silver badge7 bronze badges
1 Answer
Reset to default 2Use a switchMap
to perform the inner API call.
We use the rxjs operator filter
to prevent the inner API from triggering, essentially replacing the if (this.passwordForm.valid) {
.
The end code will look like below.
ngOnInit(): void {
if (!environment.production) {
this.toastr.info(
this.i18nextPipe.transform('In developer mode password is password.')
);
}
/**
* Subscribe to password form value changes
* Debounce logic, 1 second delay
* Distinct until changed form data, only emit if value has changed
* If data are present, data are sended to backend and if data are correct, modal is closed
*/
this.valuesChangesSubscription = this.passwordForm.valueChanges
.pipe(
debounceTime(1000),
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),
filter(() => this.passwordForm.valid),
switchMap(() => {
const data = {
password: this.passwordForm.value.password ?? '',
};
return this.appPasswordService.verifyAppPassword(data);
})
)
.subscribe({
next: (res) => {
const passwordControl = this.passwordForm.get('password');
if (
res.status === EHttpResponseCode.OK ||
res.status === EHttpResponseCode.CREATED
) {
this.modalService.closeApplicationPasswordModal();
this.toastr.success(
this.i18nextPipe.transform(
'App password is correct. Now You can fill up database config.'
)
);
}
if (res.status === EHttpResponseCode.UNAUTHORIZED) {
passwordControl?.setErrors({ incorrect: true });
this.toastr.error(
this.i18nextPipe.transform(
'App password is incorrect. Please try again.'
)
);
}
},
error: () => {
if (!environment.production) {
if (this.passwordForm.value.password === 'password') {
passwordControl?.setErrors(null);
this.modalService.closeApplicationPasswordModal();
this.toastr.success(
this.i18nextPipe.transform(
'App password is correct. Now You can fill up database config.'
)
);
} else {
passwordControl?.setErrors({ incorrect: true });
this.toastr.error(
this.i18nextPipe.transform(
'App password is incorrect. Please try again.'
)
);
}
}
},
});
}
本文标签: angularHow to simplify Rxjs functions and have only one subscribeStack Overflow
版权声明:本文标题:angular - How to simplify Rx.js functions and have only one subscribe - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741309081a2371544.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论