1
resposta

Problema com validação assíncrona

Olá pessoal,

estou tento problemas com a validação assíncrona, o erro é o seguinte:

ERROR Error: Expected validator to return Promise or Observable.
    at toObservable (forms.js:1145)
    at Array.map (<anonymous>)
    at FormControl._composedAsyncValidatorFn (forms.js:1134)
    at FormControl._runAsyncValidator (forms.js:3026)
    at FormControl.updateValueAndValidity (forms.js:3000)
    at new FormControl (forms.js:3357)
    at FormBuilder.control (forms.js:6698)
    at FormBuilder._createControl (forms.js:6736)
    at forms.js:6722
    at Array.forEach (<anonymous>)

Meu novo-usuario.service:

  verificaUsuarioExistente(nomeUsuario: string){
    return this.httpClient.get(`http://localhost:3000/user/exists/${nomeUsuario}`);
  }

Meu usuario-existe service:

usuarioJaExiste() {
    return (control: AbstractControl) => {
      return control.valueChanges?.pipe(
        switchMap((nomeUsuario) =>
          this.novoUsuarioService.verificaUsuarioExistente(nomeUsuario)
        ),
        map((usuarioExiste) =>
          usuarioExiste ? { usuarioExistente: true } : null
        ),
        first()
      );
    };
  }

Meu novo-usuario component:


  ngOnInit(): void {
    this.novoUsuarioForm = this.formBuilder.group({
      email: ['', [Validators.required, Validators.email]],
      fullName: ['', [Validators.required]],
      userName: ['', [minusculoValidator],[this.usuarioExistenteService.usuarioJaExiste()]],
      password: [''],
    });
  }

No novo-usuario template:

<app-mensagem
      *ngIf="novoUsuarioForm.get('userName')?.errors?.usuarioExistente"
      mensagem="Usuário já existente"
    ></app-mensagem>

Meu package.json:

"dependencies": {
    "@angular/animations": "~10.1.5",
    "@angular/common": "~10.1.5",
    "@angular/compiler": "~10.1.5",
    "@angular/core": "~10.1.5",
    "@angular/forms": "~10.1.5",
    "@angular/platform-browser": "~10.1.5",
    "@angular/platform-browser-dynamic": "~10.1.5",
    "@angular/router": "~10.1.5",
    "bootstrap": "^4.6.0",
    "font-awesome": "^4.7.0",
    "rxjs": "~6.6.0",
    "tslib": "^2.0.0",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1001.6",
    "@angular/cli": "^10.1.5",
    "@angular/compiler-cli": "~10.1.5",
    "@types/jasmine": "~3.5.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.11.1",
    "codelyzer": "^6.0.0",
    "jasmine-core": "~3.6.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~5.0.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~4.0.2"
  }
1 resposta

Cara, é bem provável que o erro esteja no arquivo usuario-existe.service

usuarioJaExiste() {
    return (control: AbstractControl) => {
      return control.valueChanges?.pipe(
        switchMap((nomeUsuario) =>
          this.novoUsuarioService.verificaUsuarioExistente(nomeUsuario)
        ),
        map((usuarioExiste) =>
          usuarioExiste ? { usuarioExistente: true } : null
        ),
        first()
      );
    };
  }

No return control.valueChanges, não precisa do ?, pois esse valueChanges sempre vai existir num AbstractControl. O erro acontece, pois o Validator do Angular no formulário, espera Promise | Observable e não Promise | Observable | null.

Tirando o ? deve resolver.