Solucionado (ver solução)
Solucionado
(ver solução)
9
respostas

Antes de enviar a requisição Ajax, os erros no form não são retirados.

Estou fazendo a requisição Ajax usando XMLHttpRequest e uso um if para filtrar quando devo limpar os erros do form, porém sem sucesso, gostaria de saber onde eu errei e como consertar o problema que eu causei.

Código do Form

import React, {Component} from 'react';
import PubSub from "pubsub-js";

export default class CustomInput extends Component{
    constructor(){
        super();
        this.state = {error: ''};
    }

    render(){
        return(
            <div className="pure-control-group">
                <label htmlFor={this.props.id}>{this.props.label}</label>
                <input id={this.props.id} type={this.props.type} name={this.props.name} value={this.props.value} onChange={this.props.onChange}/>
                <span className='error'>{this.state.error}</span>
            </div>  
        )
    }

    componentDidMount(){
        PubSub.subscribe('validationError', function(t, erro){
            if(erro.field === this.props.name)
                this.setState({error: erro.defaultMessage})
        }.bind(this));

        PubSub.subscribe('clean', function(t){
            this.setState({erro: ''});
        }.bind(this));
    }
}

Código do do Box

import React, {Component} from 'react';
import CustomInput from './components/CustomInput';
import SubmitButton from './components/SubmitButton';
import PubSub from 'pubsub-js';
import ErrorHandler from './ErrorHandler';


class FormAutor extends Component{
    constructor(){
        super();
        this.state = {nome: '', email: '', senha: ''};
        //bind change this to react scope
        this.sendForm = this.sendForm.bind(this);
        this.setNome = this.setNome.bind(this);
        this.setEmail = this.setEmail.bind(this);
        this.setSenha = this.setSenha.bind(this);
    }

    setNome(e){
        this.setState({nome:e.target.value})
    }

    setEmail(e){
        this.setState({email:e.target.value})
    }

    setSenha(e){
        this.setState({senha:e.target.value})
    }

   sendForm(event){
        event.preventDefault();
        //Ajax object **OLD way XMLHttpRequest**
    let url = `https://cdc-react.herokuapp.com/api/autores`;
    let xhr = new XMLHttpRequest();

        xhr.open('POST', url, true);
         xhr.setRequestHeader('Content-type', 'application/json');       
        xhr.send(JSON.stringify({nome:this.state.nome, email:this.state.email, senha:this.state.senha}));

        xhr.onreadystatechange = function(){
            if(xhr.readyState === 2 && xhr.status === 400){
                PubSub.publish("clean", {});
                console.log('limpando os erros antes de enviar');
            }else 
            //readyState 4 = finished status 200 = success
            if (xhr.readyState === 4 && xhr.status === 200) {
                this.setState({nome:'', email:'', senha:''});
                PubSub.publish('updateLista', JSON.parse(xhr.response));
            }else if(xhr.readyState === 4 && xhr.status === 400){
                new ErrorHandler().publish(JSON.parse(xhr.response));
            }
        }.bind(this);
    }

    render(){
        return(
            <div className="pure-form pure-form-aligned">
                <form className="pure-form pure-form-aligned" onSubmit={this.sendForm} method="POST">
                    <CustomInput label="Nome" id="nome" type="text" name="nome" value={this.state.nome} onChange={this.setNome} /> 
                    <CustomInput label="Email" id="email" type="email" name="email" value={this.state.email} onChange={this.setEmail} /> 
                    <CustomInput label="Senha" id="senha" type="password" name="senha" value={this.state.senha} onChange={this.setSenha} /> 
                    <SubmitButton name="Gravar" type="submit" />
                </form>             
            </div> 
        );
    }
}

class TableAutors extends Component{

    render(){
        return(
            <div>            
                <table className="pure-table">
                    <thead>
                        <tr>
                            <th>Nome</th>
                            <th>Emai

Código da validação de erro

import PubSub from "pubsub-js";

export default class ErrorHandler{
    publish(error){
        error.errors.forEach(element => {
            PubSub.publish('validationError', element);
        });
    }
}
9 respostas

Fala aí Rodrigo, tudo bem? Acho que o problema pode ser onde você está mandando limpar o form, acho que ele deveria estar dentro do segundo if e não do primeiro quando o error for 400:

if (xhr.readyState === 4 && xhr.status === 200) {
    this.setState({nome:'', email:'', senha:''});
    PubSub.publish("clean");
    PubSub.publish('updateLista', JSON.parse(xhr.response));
}

Isso porque a condição do primeiro if dificilmente irá ser true em ambos: xhr.readyState === 2 && xhr.status === 400

Espero ter ajudado.

Tentei retirar o segundo condicional,

&& xhr.status === 400

mas sem sucesso. O log aparece no console, demonstrando que o condicional é verdadeiro, mas o código de retirada da mensagem não funciona.

Não entendi Rodrigo, consegue postar o código completo?

Abaixo o código que estou usando:

 xhr.onreadystatechange = function(){
            if(xhr.readyState === 2){
                PubSub.publish("clean", {});
                console.log('limpando os erros antes de enviar');
            }else 
            //readyState 4 = finished status 200 = success
            if (xhr.readyState === 4 && xhr.status === 200) {
                this.setState({nome:'', email:'', senha:''});
                PubSub.publish('updateLista', JSON.parse(xhr.response));
            }else if(xhr.readyState === 4 && xhr.status === 400){
                new ErrorHandler().publish(JSON.parse(xhr.response));
            }
        }.bind(this);

No console do navegador aparece a mensagem de log mas as mensagens de erro que aparecem ao lado do input não somem.

Fala aí Rodrigo, beleza? Certo, se o log está aparecendo é sinal de que o .publish foi feito.

Me mostra como está o .subscribe do clean.

Fico no aguardo.

Dae Matheus, o código do .subscribe eu não alterei, continua o mesmo:

export default class CustomInput extends Component{
    constructor(){
        super();
        this.state = {error: ''};
    }

    render(){
        return(
            <div className="pure-control-group">
                <label htmlFor={this.props.id}>{this.props.label}</label>
                <input id={this.props.id} type={this.props.type} name={this.props.name} value={this.props.value} onChange={this.props.onChange}/>
                <span className='error'>{this.state.error}</span>
            </div>  
        )
    }

    componentDidMount(){
        PubSub.subscribe('validationError', function(t, erro){
            if(erro.field === this.props.name)
                this.setState({error: erro.defaultMessage})
        }.bind(this));

        PubSub.subscribe('clean', function(t){
            this.setState({erro: ''});
        }.bind(this));
    }
}
solução!

Fala aí Rodrigo, veja que no seu .setState do clean, você está passando apenas erro quando na verdade deveria ser error.

Tente fazer essa modificação, portanto, seu código ficaria:

PubSub.subscribe('clean', function(t){
    this.setState({error: ''});
}.bind(this));

Espero ter ajudado.

Realmente, preciso começar a tomar mais café pra codificar melhor, hehehe.

Obrigado pela ajuda Matheus =]

kkkkkk relaxa Rodrigo, faz parte do dia a dia.

Mágina, sempre que precisar não deixe de criar suas dúvidas.

Abraços