Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying Multiple API Responses in React

I am learning React and I have a solution that requests information through an API, and when there is a response it sets the state, however when rendering my results it only shows the last response on screen, enter image description here

Even though there are 4, see image below. enter image description here

App.js

import React from 'react';

import Tiles from './components/Tiles'
import Form from './components/Form'
import WaterData from './components/WaterData'

class App extends React.Component{

  state = {
    station_name: undefined,
    water_value: undefined,
    dateTime: undefined
  }

  getData = async (e) => {

    e.preventDefault();

    const name = e.target.elements.name.value;

    const api_call = await fetch(`https://waterlevel.ie/geojson/latest/`)
    .then(response1 => {
      response1.json().then(data =>{
        Array.from(data.features).forEach(element => {
          if(element.properties['station.name'] === name){
            this.setState({
              station_name: element.properties['station.name'],
              water_value: element.properties['value'],
              dateTime: element.properties['datetime'],
            });
          }
      })
    });
  });
}


   render(){
    return(
      <div>
        <Tiles />
        <Form loadData={this.getData}/>
        <WaterData 
           station_name={this.state.station_name}
           water_value={this.state.water_value}
           dateTime={this.state.dateTime}
        />
      </div>
   )
  }
}
export default App;

WaterData.js

import React from 'react';
const Weather = (props) => {


console.log(props)

  return(
    <li>
      <p>Location {props.station_name}</p>
      <p>Value {props.water_value}</p>
      <p>Date Time: {props.dateTime}</p>
    </li>
  )
}
export default Weather;

Can someone explain to me why the 4 responses do not display?

like image 614
Andrew Daly Avatar asked Dec 06 '25 20:12

Andrew Daly


1 Answers

This happens because you are replacing the values in your state for each part of your data.

You can filter out the element you want in your array using filter.

And then put the whole array into your state only once :

const api_call = await fetch(`https://waterlevel.ie/geojson/latest/`)
.then(response1 => {
  response1.json().then(data => {
    const features = Array.from(data.features)
      .filter(el => el.properties['station.name'] === name);
    this.setState({ features });
  })
});

But now, to render all of them, you will need to map your state values :

   render(){
    return(
      <div>
        <Tiles />
        <Form loadData={this.getData}/>
        {this.state.features.map(feat => <WaterData 
           key={/* Find something unique*/}
           station_name={feat.properties['station.name']}
           water_value={feat.properties['value']}
           dateTime={feat.properties['datetime']}
        />)}
      </div>
    )
  }

There's no need to store all the value separately in your state if they are related to each other, it would be fine for your child component though.

To be sure that the state value is always an array, give it an empty array at the start of your class :

  state = {
    features: []
  }
like image 138
Treycos Avatar answered Dec 09 '25 10:12

Treycos