Home > other >  add validations before returning observable in Angular
add validations before returning observable in Angular

Time:09-17

Everytime the button is clicke and if If modelform is invalid then return notification message and not proceed to creating a user (createUser).

it should only proceed on returning this.accountService.create if there is no form validation error

Is the function cleanly and correctly implemented ? is there some major problem that causes the issue ? Thanks.

where do I put the checkInputs validations that if there is validation error it should not proceed on this.accountService.create

#html code

 <button #createUserBtn mat-flat-button color="primary" >Create
                    User</button>

#code

@ViewChild('createUserBtn', { static: true, read: ElementRef })
  button: ElementRef;


  ngAfterViewInit(): void {
    fromEvent(this.button.nativeElement, 'click')
      .pipe(
        tap(x => x),
        exhaustMap(ev => {
          return this.createUser();
        })
      )
      .pipe(tap(x => x))
      .subscribe(this.handleResponse());
  }

  createUser(): Observable<any> {
    this.checkInputs();
    this.isInProgress = true;
    this.modelForm.markAllAsTouched();
    return this.accountService.create(this.modelForm.value).pipe(
        finalize(() => (this.isInProgress = false))
    );
  }

  handleResponse(): any {
    return {
      next: res => {
        this.notificationService.showSuccess('User has been created successfully.');
        this._router.navigate(['settings/user']);
      },
      error: err => {
        this.notificationService.showError('Something went wrong, Try again later.');
        this.isInProgress = false;
      },
      complete: () => this.isInProgress = false
    };
  }

  checkInputs() {
    if(this.userStatus == 'USER_ON_NO_ACCOUNT') {

      if(!this.modelForm.get('firstName').value) {
        this.notificationService.showError('First Name is required.');
        return;
      }

      if(!this.modelForm.get('lastName').value) {
        this.notificationService.showError('Last Name is required.');
        return;
      }

      if(!this.modelForm.get('companyName').value) {
        this.notificationService.showError('Company Name is required.');
        return;
      }
    }
    
    if(!this.modelForm.get('roleId').value) {
      this.notificationService.showError('Security Role is required.');
      return;
    }

    if(this.modelForm.get('roleId').value && this.modelForm.get('roleId').value !== 7 && !this.modelForm.get('isSso').value) {
      this.notificationService.showError('SSO is required.');
      return;
    }

    if(this.modelForm.get('roleId').value && this.modelForm.get('isSso').value && this.modelForm.get('isSso').value ==='Yes' && !this.modelForm.get('ssocredentials').value) {
      this.notificationService.showError('SSO Credential is required.');
      return;
    }

    if(this.modelForm.get('isSso').value ==='No') {
      this.modelForm.get('ssocredentials').setValue(null);
    }
  }

CodePudding user response:

You can add the invalid check before this.accountService.create(this.modelForm.value), but you have to change the click event handler to be like the following:

  • There is no need to handle the click event this way, and instead, you can add the event handler directly from the template:
<button mat-flat-button color="primary" (click)="createUser()">
  Create User
</button>
  • There is no need to chain the createUser with the other observables, the and same for handleResponse. Instead, you can subscribe to the accountService.create function within createUser method and handle the success and fail within it also, like the following:
createUser(): void {
  this.checkInputs();
  this.isInProgress = true;
  this.modelForm.markAllAsTouched();

  // here you can check if the form is valid or not:
  if (this.modelForm.invalid) return;

  this.accountService.create(this.modelForm.value)
    .pipe(
      // take(1) is used to complete the observable after the result comes.
      take(1),
      catchError((err) => {
        this.notificationService.showError(
          'Something went wrong, Try again later.'
        );
        this.isInProgress = false;
        return EMPTY;
      }),
      finalize(() => (this.isInProgress = false))
    )
    .subscribe((res) => {
      this.notificationService.showSuccess(
        'User has been created successfully.'
      );
      this._router.navigate(['settings/user']);
    });
}
  • You can remove the ngAfterViewInit block, handleResponse method, and the button @ViewChild, because the above createUser will handle that, and complete the observable directly after receiving the result from the service.
  • Related