4

I'm learning React, I made a page with Form.

This Form should get data from back-end via axios. I need help because whatever I do, array doesn't display in the select options.

Example of data:

[{"country": "Germany" "code": 112 }]

import React, { Component } from 'react';
import { Row, Col, Button, Form } from 'react-bootstrap';
import axios from 'axios';

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            country: []

        };
    }
    componentDidMount() {
        axios
            .get('URL')
            .then((response) => {
                console.log(response);

                this.setState({
                    country: response
                });
            })
            .catch((error) => console.log(error.response));
    }
    handleChangeCountry = (event) => {
        this.setState({ country: event.target.value });
    };

    inputCountryHandler = (event) => {
        this.setState({
            input: {
                country: event.target.value
            }
        });
    };

    render() {
        //  const { country} = this.state;

        return (
            <Form className="calculator-table">
                <Form.Group controlId="first-row" className="Focus-line">
                    <Form.Label>Country</Form.Label>
                    <Form.Control
                        as="select"
                        className="User-Input"
                        placeholder=""
                        value={this.state.country}
                        onChange={this.handleChangeCountry}
                        id="country"
                        option={this.country}
                    />
                </Form.Group>

        );
    }
}

export default Form;

I want the array data to be displayed in drop down select.

Thanks for any answer

Nat
  • 71
  • 2
  • 9

4 Answers4

2

You should first parse the JSON response from the API.

componentDidMount() {
        axios
            .get('URL')
            .then((response) => {
                console.log(response);

                this.setState({
                    country: JSON.parse(response) //parse the response
                });
            })
            .catch((error) => console.log(error.response));
    }
Michael
  • 325
  • 1
  • 10
2

As per the docs, Form.Control don't accept option as props.

You must iterate your country array to get the options.


<Form.Control
    as = "select"
    className = "User-Input"
    placeholder = ""
    value = { this.state.selectedCountry }
    onChange = { this.handleChangeCountry }
    id = "country"  //Remove this id, otherwise you will get the warning
> 
    {
        this.state.country && this.state.country.length > 0 && this.state.country.map(countryItem => <option key={countryItem.country}>{countryItem.country}</option>)
    } 
</Form.Control>

You should have a separate state variable to store the selected value,

constructor(props) {
    super(props);
    this.state = {
       country: [],
       selectedCountry: ''  //add this to store selected country value
    };
}

And your handleChangeCountry function should be,

handleChangeCountry = (event) => {
    this.setState({ selectedCountry: event.target.value });
};

Note: axios return response in JSON format, but the actual data is in response.data, so you should set your state as,

this.setState({
      country: response.data
});

When you specify id = 'country', you will get warning,

Warning: controlId is ignored on <FormControl> when id is specified.

You should remove the id = 'country'.

ravibagul91
  • 20,072
  • 5
  • 36
  • 59
  • I tried your solution, thank you for quick response, and I have changed evertyhing like you wrote, and ofc delete id='country'. I have TypeError: Cannot read property 'map' of undefined – Nat Sep 03 '19 at 05:47
  • Have you deleted `country: []` from your state? You should keep it in state only along with `selectedCountry: ''`. You can check the updated answer. – ravibagul91 Sep 03 '19 at 05:54
  • Ok, There is no error now :) But there is still no data in option select : – Nat Sep 03 '19 at 06:05
  • In your axios call, are you getting response correctly? Check `console.log(response.data);` – ravibagul91 Sep 03 '19 at 06:06
1

I believe the issue is that the Form.Control component as select expects options as children components. So you would need to map over the response array like so:

<Form.Control as="select">
    {this.state.country.map(response => {
        <option>{response.country}</option>
    })}
</Form.Control>
0

According to docs you must use array of option

<Form.Control
    as="select"
    className="User-Input"
    placeholder=""
    value={this.state.country}
    onChange={this.handleChangeCountry}
    id="country">
    {
        this.state.country.map((c, i) => <option value={c.code} key={i}>{c.country}</option>)
    }
</Form.Control>

Also, you have to use 2 state variables, example

this.state = {
    selectedCountries: [], // from select control
    country: []            // from backend
}

And populate select value from this.state.selectedCountries

Medet Tleukabiluly
  • 11,662
  • 3
  • 34
  • 69