Пользовательская асинхронная проверка угловой реактивной формы из ответа API - PullRequest
0 голосов
/ 30 ноября 2018

Я новичок в Angular (V6) и там вроде как заблудился.Я искал ответ на свою проблему, но после нескольких дней исследований я не смог найти то, что искал.Надеюсь, вы, ребята, поможете мне.

Я разработал API, в котором есть конечная точка для регистрации учетной записи.По запросу POST сервер просто проверяет, все ли в запросе тела в порядке, в противном случае он отправляет JSON с ошибками поля (например, имя пользователя уже занято или слишком коротко, несоответствие паролей, адрес электронной почты уже занят и т. Д.).

Я хотел использовать асинхронную проверку в моей реактивной форме, когда я отправляю ее, чтобы я мог получить ответ сервера и отобразить ошибки в форме.Но мне не удалось это сделать.Для меня нет четкого примера в документах Angular для этого случая.

sign-up.component.ts

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

import { ApiService } from './../../services/api.service';

@Component({
  selector: 'app-sign-up',
  templateUrl: './sign-up.component.html',
  styleUrls: ['./sign-up.component.scss']
})
export class SignUpComponent implements OnInit {

  signupForm: FormGroup;

  constructor(
    private formBuilder: FormBuilder,
    private apiService: ApiService
  ) { }

  ngOnInit() {
    this.initForm();
  }

  initForm() {
    this.signupForm = this.formBuilder.group({
      firstname: ['', Validators.required],
      lastname: ['', Validators.required],
      username: ['', Validators.required],
      email: ['', Validators.required],
      password: ['', Validators.required],
      confirmPassword: ['', Validators.required],
      birthdate: ['', Validators.required],
      gender: ['', Validators.required]
    }, {
      asyncValidator: this.myAsyncValidator() // Am I wrong?
    });
  }

  onSubmitForm() {
    console.log('submit');
    // On submit, I send the form to the server.
    // If the account has been created, I redirect the user (no problem for that)
    // but if there are some errors, I would like to display them into the form.
  }

  myAsyncValidator () {
    // I'm lost here
  }
}

api.service.ts

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

const apiURL = 'MY_SERVER_URL';

@Injectable({
  providedIn: 'root'
})
export class ApiService {

  constructor(private http: HttpClient) { }

  signUp(data: Object) {
    const body = JSON.stringify(data);
    return this.http.post(`${apiURL}/authentication/signup/`, body, httpOptions);
  }
}

sign-up.component.html

<div class="signup-container">
  <div class="mx-auto">
    <form [formGroup]="signupForm" (ngSubmit)="onSubmitForm()">
      <mat-form-field>
        <input matInput placeholder="Prénom" formControlName="firstname">
      </mat-form-field>

      <mat-form-field>
        <input matInput placeholder="Nom" formControlName="lastname">
      </mat-form-field>

      <mat-form-field>
        <input matInput placeholder="Pseudo" formControlName="username">
      </mat-form-field>

      <mat-form-field>
        <input matInput type="email" placeholder="Email" formControlName="email">
      </mat-form-field>

      <mat-form-field>
        <input matInput type="password" placeholder="Mot de passe" formControlName="password">
      </mat-form-field>

      <mat-form-field>
        <input matInput type="password" placeholder="Confirmer le mot de passe" formControlName="confirmPassword">
      </mat-form-field>

      <mat-form-field>
        <input matInput [matDatepicker]="picker" placeholder="Date de naissance" formControlName="birthdate" (focus)="picker.open()">
        <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
        <mat-datepicker #picker></mat-datepicker>
      </mat-form-field>

      <mat-radio-group formControlName="gender">
        <mat-radio-button value="Femme">Femme</mat-radio-button>
        <mat-radio-button value="Homme">Homme</mat-radio-button>
      </mat-radio-group>

      <button type="submit" mat-stroked-button class="save-button"><i class="material-icons save-icon">save</i>Inscription</button>
    </form>
  </div>
</div>

1 Ответ

0 голосов
/ 30 ноября 2018

Я нашел решение своей проблемы.Я переключился с реактивной формы на шаблонную форму.Я знаю, что это не лучшее решение, я постараюсь найти лучший способ решить это.Надеюсь, это кому-нибудь поможет!

Вот что я сделал:

sign-up.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { NgForm } from '@angular/forms';

import { ApiService } from './../../services/api.service';

@Component({
  selector: 'app-sign-up',
  templateUrl: './sign-up.component.html',
  styleUrls: ['./sign-up.component.scss']
})
export class SignUpComponent implements OnInit {
  isSending = false;
  submitText = 'Inscription';

  constructor(
    private apiService: ApiService,
    private router: Router
  ) { }

  ngOnInit() { }

  onSubmit(formData: NgForm) {
    this.isSending = true;
    this.submitText = 'Inscription en cours...';
    this.apiService.signUp(formData.value).subscribe(
      response => {
        this.router.navigate(['/signin']);
      },
      error => {
        const errors = error.error.message.errors; // Yeah... Mongoose validator...
        for (const fieldError in errors) {
          if (errors[fieldError]) {
            formData.form.controls[fieldError].setErrors({ invalid: errors[fieldError]['message'] });
          }
        }
        this.isSending = false;
        this.submitText = 'Inscription';
      }
    );
  }
}

sign-up.component.html

<div class="signup-container">
  <div class="mx-auto">
    <form (ngSubmit)="onSubmit(f)" #f="ngForm">
      <mat-form-field>
        <input matInput placeholder="Prénom" ngModel name="firstname" #firstname="ngModel">
        <mat-error *ngIf="firstname.errors">{{firstname.errors['invalid']}}</mat-error>
      </mat-form-field>

      <mat-form-field>
        <input matInput placeholder="Nom" ngModel name="lastname" #lastname="ngModel">
        <mat-error *ngIf="lastname.errors">{{lastname.errors['invalid']}}</mat-error>
      </mat-form-field>

      <mat-form-field>
        <input matInput placeholder="Pseudo" ngModel name="username" #username="ngModel">
        <mat-error *ngIf="username.errors">{{username.errors['invalid']}}</mat-error>
      </mat-form-field>

      <mat-form-field>
        <input matInput type="email" placeholder="Email" ngModel name="email" #email="ngModel">
        <mat-error *ngIf="email.errors">{{email.errors['invalid']}}</mat-error>
      </mat-form-field>

      <mat-form-field>
        <input matInput type="password" placeholder="Mot de passe" ngModel name="password" #password="ngModel">
        <mat-error *ngIf="password.errors">{{password.errors['invalid']}}</mat-error>
      </mat-form-field>

      <mat-form-field>
        <input matInput type="password" placeholder="Confirmer le mot de passe" ngModel name="confirmPassword" #confirmPassword="ngModel">
        <mat-error *ngIf="confirmPassword.errors">{{confirmPassword.errors['invalid']}}</mat-error>
      </mat-form-field>

      <mat-form-field>
        <input matInput [matDatepicker]="picker" placeholder="Date de naissance" ngModel name="birthdate" #birthdate="ngModel" (focus)="picker.open()">
        <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
        <mat-datepicker #picker></mat-datepicker>
        <mat-error *ngIf="birthdate.errors">{{birthdate.errors['invalid']}}</mat-error>
      </mat-form-field>

      <mat-radio-group ngModel name="gender" #gender="ngModel">
        <mat-radio-button value="Femme">Femme</mat-radio-button>
        <mat-radio-button value="Homme">Homme</mat-radio-button>
        <mat-error *ngIf="gender.errors">{{gender.errors['invalid']}}</mat-error>
      </mat-radio-group>

      <button type="submit" mat-stroked-button class="save-button" [disabled]="isSending">
        <i class="material-icons save-icon">save</i>{{submitText}}
      </button>
    </form>
  </div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...