3
respostas

Erro 404 validação assincrona

Estou acompanhando o curso na lição de validação de formulário. tenho o seguindo componente

  constructor(
        public formBuilder: FormBuilder,
        private cadUsuarioValidatorService: CadUsuarioValidatorService,
        private cadUsuarioService: CadUsuarioService,
        private router: Router
        ){
            this.cadUsuarioForm = this.formBuilder.group({
                fullName: new FormControl('', Validators.compose([
                    Validators.required,
                    Validators.minLength(5),
                    Validators.maxLength(140)
                ])),
                cpf: new FormControl('', Validators.compose([
                    Validators.required,
                    cpfValidator
                ]), 
                    this.cadUsuarioValidatorService.checkCPFTaken()
                ),
                email: new FormControl('', Validators.compose([
                    Validators.required,
                    Validators.email
                ]),
                    this.cadUsuarioValidatorService.checkEmailTaken()
                ),
                password: new FormControl('', Validators.compose([
                    Validators.required,
                    Validators.minLength(8),
                    Validators.maxLength(14)
                ])),
                confirmPassword: new FormControl('', Validators.compose([
                    Validators.required,
                    Validators.minLength(8),
                    Validators.maxLength(14)
                ]))
            },{
               validator: confirmPasswordValidator('password', 'confirmPassword')
            });
        }

Na validação de CPF que valida se o cpf já esta cadastrado, quando eu informo um cpf não cadastrado a api retorna 404 então o formulário deveria validar. No entanto ele da erro de pending e não habilita o botão de salvar. segue html usado

    <button [disabled]="cadUsuarioForm.invalid || cadUsuarioForm.pending"                                 
                                mat-raised-button color="primary" 
                                class="btn-block btn-lg m-t-20 m-b-20" 
                                type="submit">Gravar</button>  

aqui estão as funções de validação

 checkCPFTaken() {
     return (control: AbstractControl) => {     
        return control
            .valueChanges
            .pipe(debounceTime(300))
            .pipe(switchMap(cpf =>
                this.cadUsuarioService.checkCPFTaken(cpf)
            ))
            .pipe(map(isTaken => isTaken ? { cpfTaken: true } : null ))
            .pipe(first());
     }
    }
    checkEmailTaken() {
        return (control: AbstractControl) => {     
           return control
               .valueChanges
               .pipe(debounceTime(300))
               .pipe(switchMap(email =>
                    this.cadUsuarioService.checkEmailTaken(email)
               ))
               .pipe(map(isTaken => isTaken ? { emailTaken: true } : null ))
               .pipe(first());
        }
       }    
3 respostas

Fala ai Gustavo, tudo bem? Eu chutaria que o this.cadUsuarioService.checkCPFTaken(cpf) esteja dando um erro por conta do 404, talvez você vai precisar tratar isso, para somente considerar erro quando der status 500.

Se quiser, compartilha o projeto completo comigo, assim consigo simular o problema por aqui e analisá-lo com mais calma.

Pode compartilhar através do Github ou Google Drive (zipado).

Espero ter ajudado.

   checkEmailTaken() {
        return (control: AbstractControl) => {     
           return control
               .valueChanges
               .pipe(debounceTime(300))
               .pipe(switchMap(email =>
                    this.cadUsuarioService.checkEmailTaken(email)
               ))
               .pipe(map(isTaken => isTaken ? { emailTaken: true } : null ))
               .pipe(first());
        }
       } 

Aqui eu faço a geração do parâmetro. Mudei a API para retornar assim:

{
    "emailTaken": true,
    "message": "Email já cadastrado!"
}

quando o Email já estiver cadastrado e nesse caso eu não permito o cadastrar com o mesmo e-mail. E assim:

{
    "emailTaken": false,
    "message": "Email não encontrado!"
}

Quanto o email não constar na base de dados.

A questão é se o parâmetro emailTaken (da api) retornar true o emailTaken do validator deve ser null para não deixar cadastrar ao contrário ele deve ser true e permitir cadastar

Eu também tenho um cadusuario.service.ts

   checkEmailTaken(email: string){
        let params = new HttpParams().set("email", email)        
        return this.http.get(API_URL + '/auth/verificaExtEmail',{params});
    }

Que retorna um observable para o validator. Esse é o que chega para mim:

{isTaken: false, message: "Email não encontrado!"}
isTaken: false
message: "Cpf não encontrado!"
__proto__: Object
cadusuario.validator.service.ts:21 
{isTaken: true, message: "Email já cadastrado!"}
isTaken: true
message: "Cpf já cadastrado!"
__proto__: Object

como eu acesso na função chekEmailTaken o valor da variável para tratar o retorno?

Fala Gustavo, consegue compartilhar o projeto completo comigo? Tanto o front quanto o back, dessa maneira eu consigo simular a situação localmente na minha máquina e te ajudo com mais objetividade (isso porque preciso ver a arquitetura do projeto angular, como está a API e tals).

Pode subir no Github ou Google Drive (zipado).

Espero ter ajudado.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software