1

I try to fill in a dropdown with data from the JSON format but for now the dropdown is empty (no results found...)

I certainly have a mistake and I can not understand where I'm confusing.

I will attach a screen of my API.

I want to get Station and NameStation..

API for Stations

My code:

import React, { Component } from 'react';
import Select from 'react-select';
import 'react-select/dist/react-select.css';

function parseStations(stations){
  return stations.map((station) => {
    return { label: station.NameStation, value: station.Station };
  });
}

export default class Weather extends Component {
  constructor(props) {
    super(props);
    this.state = {
      options: [
        { value: true, label: 'Yes' },
        { value: false, label: 'No' }
      ], stations: [

      ],
      value: null
    }
    this.onChange = this.onChange.bind(this);
  }
  onChange(event) {
    this.setState({ value: event.value });
    console.log('Boolean Select value changed to', event.value);
  }

  componentDidMount() {
    this.getStations();
  }

  getStations() {
    fetch('http://localhost:56348/api/stations', {
      data: 'Station',
      data: 'NameStation',
      method: "GET"
    }).then(res => res.json())
      .then(res => this.setState({ stations: parseStations(res.stations) }))
      //.then(res => this.setState({ stations: res.stations }))
      //.catch(e => )
  }

  render() {
    return (
      <div className="MasterSection">
        <div className="wrapper">
          <div className="section">Изберете № на станция</div>
          <Select
            onChange={this.onChange}
            //options={this.state.options}
            options={this.state.stations}
            value={this.state.value}
            clearable={false}
          />
        </div>
        <div class="section">
          <input type="text" class="form-control" placeholder="Брой дни назад" aria-label="Username" aria-describedby="basic-addon1"></input>
        </div>
        <div class="section">
          <button type="button" class="btn btn-outline-dark">Покажи</button>
        </div>
      </div>
    );
  }
}

2 Answers 2

3

Seems you made a typo naming the prop stations instead of options :

<Select
    onChange={this.onChange}
    options={this.state.stations} // here
    value={this.state.value}
    clearable={false}
/>

Edit : you'll need to parse your json first to pass a proper array of objects like this : [{ label: nameStation, value: Station }]

Edit 2 : Here's a parser for your data :

function parseStations(stations){
  return stations.map((station) => {
    return { label: station.NameStation, value: station.Station };
  });
}

You can call this in your async request before setting the state :

.then(res => this.setState({ stations: parseStations(res.stations) }))
Sign up to request clarification or add additional context in comments.

6 Comments

@ZlatkaPijeva place the parseStations function outside of your component class or declare it as a method (remove "function" if you declare as a method)
Now I have only two errors: Line 19: 'Station' is not defined no-undef Line 19: 'NameStation' is not defined no-undef
@ZlatkaPijeva you added [{ label: nameStation, value: Station }] in your initial state, i wrote this just to illustrate the object format you need to pass to the Select options, just remove this and set the initial state to an empty array like you did before : stations: [ ]
I remove [{ label: nameStation, value: Station }] and leave empty array, but dropdown is still empty (no results found) :(
@ZlatkaPijeva maybe change res.stations to res.stations.Stations
|
1
  1. componentDidMount() is executed only after render() is completed. so there's no way getStations() gets executed at the time your UI gets rendered. it is not a good idea to setState inside componentDidMount() as it triggers re rendering. use componentWillMount() instead.

  2. correct the typo that Dyo mentioned and use options={this.state.stations}

3 Comments

Fetching data in componentDidMount() is a good practice, you can't expect to have the data before the first render using componentWillMount() so you'll also need to set an initial state and the rerendering will occur too. (also componentWillMount will be deprecated in the future)
@Dyo I got your point, my concern was only with the setState. since fetch() is async in nature there's no way to separate them in two different functionality as well. do you think setState() inside componentDidMount() is OK to go with?
Yes it is when you setState in async functions, for sync operations constructor is a better option.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.