GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Dropdown do primereact

Tags: #<Tag:0x00007f4c28adc2c8>

Estou precisando preencher o componente Dropdown do primereact, de informações que vem do banco de dados, mas está ficando em branco.

Nesta parte do código ele vai no backend, mas mesmo assim não está preenchendo as informações no componente.

       let a = [
          ApiGrupoService.todos().then(
            res => {
              return res;
          })
        ]

Código completo

import React, { Component } from 'react';

import ApiUsuarioService from '../../service/ApiServiceUsuario';
import ApiGrupoService from '../../service/ApiServiceGrupo';

import {InputText} from 'primereact/inputtext';
import {Button} from 'primereact/button';
import {Growl} from 'primereact/growl';
import {Calendar} from 'primereact/calendar';
import {Dropdown} from 'primereact/dropdown';

class UsuarioForm extends Component {

  constructor(props) {
    super(props);
    this.usuario = {
        id: null,
        grupo: null,
        nome: null,
        sobrenome: null,
        dataAniversario: null
    }
    this.salvarUsuario = this.salvarUsuario.bind(this);
  }

  salvarUsuario = (e) => {
    e.preventDefault();
    let usuario = {id: this.state.id, 
      grupo: this.state.grupo,
      nome: this.state.nome,
      sobrenome: this.state.sobrenome,
      dataAniversario: this.state.dataAniversario};
      ApiUsuarioService.salvar(usuario).then(res => {
        this.growl.show({severity: res.data.tipoMensagem.tipo, 
            summary: res.data.tipoMensagem.sumario, 
            detail: res.data.tipoMensagem.mensagem});
      }, (err) => {
          this.growl.show({severity: err.response.data.tipoMensagem.tipo, 
              summary: err.response.data.tipoMensagem.sumario, 
              detail: err.response.data.tipoMensagem.mensagem});
      });
  }

  render() {

    let a = [
      ApiGrupoService.todos().then(
        res => {
          return res;
      })
    ]
    
    return (
      <div>
            <Growl ref={el => (this.growl = el)} />
            <h1>Grupo *</h1>
            <Dropdown value={this.usuario.grupo} options={a}
              onChange={(e) => {this.setState({grupo: e.value})}} 
              placeholder="Selecione o grupo"/>
            <h1>Nome *</h1>
            <InputText value={this.usuario.nome} 
                onChange={(e) => this.setState({nome: e.target.value})} /><br/>
            <h1>Sobrenome *</h1>
            <InputText value={this.usuario.sobrenome} 
                onChange={(e) => this.setState({sobrenome: e.target.value})} /><br/>
            <h1>Aniversário *</h1>
            <Calendar value={this.usuario.dataAniversario} dateFormat="dd/mm/yy"
                onChange={(e) => this.setState({dataAniversario: e.value})} /><br/>
            <Button onClick={this.salvarUsuario} label="Salvar" />
        </div>
    );
  }
}

export default UsuarioForm;

Erro no console do navegador:

index.js:1375 Warning: Each child in a list should have a unique "key" prop.

Check the render method of `Dropdown`. See https://fb.me/react-warning-keys for more information.
    in DropdownItem (created by Dropdown)
    in Dropdown (at usuario-form.js:64)
    in div (at usuario-form.js:61)
    in UsuarioForm (created by Context.Consumer)
    in Route (at src/index.js:17)
    in Switch (at src/index.js:14)
    in Router (created by BrowserRouter)
    in BrowserRouter (at src/index.js:13)

As atualizações não estão ocorrendo pq o seu objeto não esta setado no state.
Quando o state muda, o render é executado novamente atualizando os valores.

Coloca o seu usuario dentro do state

Não entendi …

ApiGrupoService.todos().then(
    res => {
      return res;
  })

Executa essa chamada no componentDidMount e seta no state o response
Ex:

componentDidMount() {
  this.setState({
    grupos: [ApiGrupoService.todos().then(
      res => {
        return res;
      }
    )
  })
}

No Dropdown você passa os grupos

<Dropdown value={this.usuario.grupo} options={this.state.grupos}
              onChange={(e) => {this.setState({grupo: e.value})}} 
              placeholder="Selecione o grupo"/>

Os componentes do seu render só vão ter o valor atualizado caso o state ou props mude.

Fiz assim e não está chamando mais o backend.

import React, { Component } from 'react';

import ApiUsuarioService from '../../service/ApiServiceUsuario';
import ApiGrupoService from '../../service/ApiServiceGrupo';

import {InputText} from 'primereact/inputtext';
import {Button} from 'primereact/button';
import {Growl} from 'primereact/growl';
import {Calendar} from 'primereact/calendar';
import {Dropdown} from 'primereact/dropdown';

class UsuarioForm extends Component {

  constructor(props) {
    super(props);
    this.usuario = {
        id: null,
        grupo: null,
        nome: null,
        sobrenome: null,
        dataAniversario: null
    }
    this.salvarUsuario = this.salvarUsuario.bind(this);
  }

  salvarUsuario = (e) => {
    e.preventDefault();
    let usuario = {id: this.state.id, 
      grupo: this.state.grupo,
      nome: this.state.nome,
      sobrenome: this.state.sobrenome,
      dataAniversario: this.state.dataAniversario};
      ApiUsuarioService.salvar(usuario).then(res => {
        this.growl.show({severity: res.data.tipoMensagem.tipo, 
            summary: res.data.tipoMensagem.sumario, 
            detail: res.data.tipoMensagem.mensagem});
      }, (err) => {
          this.growl.show({severity: err.response.data.tipoMensagem.tipo, 
              summary: err.response.data.tipoMensagem.sumario, 
              detail: err.response.data.tipoMensagem.mensagem});
      });
  }


  componentDidMount() {
    this.setState({
      grupos: [ApiGrupoService.todos().then(
        res => this.setState({usuarios: res.data.lista})
      )]
    })
  }
  
  render() {
    
    return (
      <div>
            <Growl ref={el => (this.growl = el)} />
            <h1>Grupo *</h1>
            <Dropdown value={this.usuario.grupo} options={this.state.grupos}
              onChange={(e) => {this.setState({grupo: e.value})}} 
              placeholder="Selecione o grupo"/>
            <h1>Nome *</h1>
            <InputText value={this.usuario.nome} 
                onChange={(e) => this.setState({nome: e.target.value})} /><br/>
            <h1>Sobrenome *</h1>
            <InputText value={this.usuario.sobrenome} 
                onChange={(e) => this.setState({sobrenome: e.target.value})} /><br/>
            <h1>Aniversário *</h1>
            <Calendar value={this.usuario.dataAniversario} dateFormat="dd/mm/yy"
                onChange={(e) => this.setState({dataAniversario: e.value})} /><br/>
            <Button onClick={this.salvarUsuario} label="Salvar" />
        </div>
    );
  }
}

export default UsuarioForm;

e assim:

import React, { Component } from 'react';

import ApiUsuarioService from '../../service/ApiServiceUsuario';
import ApiGrupoService from '../../service/ApiServiceGrupo';

import {InputText} from 'primereact/inputtext';
import {Button} from 'primereact/button';
import {Growl} from 'primereact/growl';
import {Calendar} from 'primereact/calendar';
import {Dropdown} from 'primereact/dropdown';

class UsuarioForm extends Component {

  constructor(props) {
    super(props);
    this.usuario = {
        id: null,
        grupo: null,
        nome: null,
        sobrenome: null,
        dataAniversario: null
    }
    this.salvarUsuario = this.salvarUsuario.bind(this);
  }

  salvarUsuario = (e) => {
    e.preventDefault();
    let usuario = {id: this.state.id, 
      grupo: this.state.grupo,
      nome: this.state.nome,
      sobrenome: this.state.sobrenome,
      dataAniversario: this.state.dataAniversario};
      ApiUsuarioService.salvar(usuario).then(res => {
        this.growl.show({severity: res.data.tipoMensagem.tipo, 
            summary: res.data.tipoMensagem.sumario, 
            detail: res.data.tipoMensagem.mensagem});
      }, (err) => {
          this.growl.show({severity: err.response.data.tipoMensagem.tipo, 
              summary: err.response.data.tipoMensagem.sumario, 
              detail: err.response.data.tipoMensagem.mensagem});
      });
  }


  componentDidMount() {
    this.setState({
      grupos: [ApiGrupoService.todos().then(
        res => this.setState({usuarios: res.data.lista})
      )]
    })
  }
  
  render() {
    
    componentDidMount() {
      this.setState({
        grupos: [ApiGrupoService.todos().then(
          res => this.setState({usuarios: res.data.lista})
        )]
      })
    }

    return (
      <div>
            <Growl ref={el => (this.growl = el)} />
            <h1>Grupo *</h1>
            <Dropdown value={this.usuario.grupo} options={this.state.grupos}
              onChange={(e) => {this.setState({grupo: e.value})}} 
              placeholder="Selecione o grupo"/>
            <h1>Nome *</h1>
            <InputText value={this.usuario.nome} 
                onChange={(e) => this.setState({nome: e.target.value})} /><br/>
            <h1>Sobrenome *</h1>
            <InputText value={this.usuario.sobrenome} 
                onChange={(e) => this.setState({sobrenome: e.target.value})} /><br/>
            <h1>Aniversário *</h1>
            <Calendar value={this.usuario.dataAniversario} dateFormat="dd/mm/yy"
                onChange={(e) => this.setState({dataAniversario: e.value})} /><br/>
            <Button onClick={this.salvarUsuario} label="Salvar" />
        </div>
    );
  }
}

export default UsuarioForm;

Está última dá erro de código no visual studio

erro

O componentDidMount é fora do render,

E ai tem uma coisa errada, você ta dando um setState dentro do setState

Você tentou com o código que postei?

Dá este erro e não vai no back end

Isso é pq você não criou o state no construtor

this.state = {
    grupos: {

    }
}

Agora deu este erro:

items é um array?

Entendo que itens, é o retorno do JSON do banco de dados

  componentDidMount() {
    this.setState({
      grupos: [ApiGrupoService.todos().then(
        res => {
          return res.data.lista;
        }
      )]
    })
  }

Dessa maneira retorna uma lista, mas continua dando o mesmo erro.

Você esta passando this.state.grupos na propriedade options do DropDown, talvez esse itens é a variável que é declarada internamente no DropDown e ai ela ta acusando que this.state.grupos não é um array (o erro .map is not a function acontece quando o a variavel que esta invocando a função map não é um array)

Tenho que fazer a conversão para map ?

Não, this.state.grupos tem que ser um array, você tem certeza que é?

Da um console.log nele e posta aqui.

Pra pegar o valor do estado logo após o setState, você tem que fazer que nem o código abaixo:

this.setState({
      grupos: [ApiGrupoService.todos().then(
        res => {
          return res.data.lista;
        }
      )]
    }, console.log("grupos", this.state.grupos));

o resp.data.lista é um array.

o this.state.grupos vem vazio

erro

Então é um array mesmo. Acho que ja sei o que é.

Falei para você deixar assim o código:

this.state = {
    grupos: {

    }
}

Mas na verdade, tem que ser assim:

this.state = {
    grupos: [

    ]
}

O grupos tem que ser um par de colchetes e não chaves.

Antes dessa requisição terminar, o render esta sendo executado, e ai o this.state.grupos ainda é um objeto, ai só quando a requisição termina, que ele vira um array populado, o certo é deixar ele como array inicialmente.

Ve ai

Vai no backend, mas não atualiza o componente.

//