1

I was tasked to create a front-end for a poc. I am not a front end developer but I chose to use React JS. There is only one page fetching data from multiple API endpoints. API endpoints return a simple json object. I managed to get that to work however my code is ugly af and I want to create a function to handle all of that but I can't seem to get it right. Here's my code

export default class Dashboard extends React.Component {

constructor(props) {
    super(props);
    this.state = {
      group1: [],
      group2: [],
      group3: [],
      isLoaded: false,
    }
  }

componentDidMount() {
    const group1_url = "http://localhost/api/1"
    const group2_url = "http://localhost/api/2"
    const group3_url = "http://localhost/api/3"

    fetch(group1_url)
      .then(res => res.json())
      .then(json => {
        this.setState({
          group1: json,
        })
      });
    fetch(group2_url)
      .then(res => res.json())
      .then(json => {
        this.setState({
          group2: json,
        })
      });
    fetch(group3_url)
      .then(res => res.json())
      .then(json => {
        this.setState({
          group3: json,
        })
      });
  }

I am trying to create a function like this:

 function fetch_data(url, state) {
    fetch(url)
      .then(res => res.json())
      .then(json => {
        this.setState({
          state: json,
        })
      });
  }

var group1 = fetch_data(group1_url, group1);

So far no joy. How can I create a function to fetch data and set a state in js? Alternatively how can I make my code look better? Or is there something else I should use/look into?

3 Answers 3

2

Pass a string as the second parameter, and use a computed property:

function fetch_data(url, state) {
    fetch(url)
      .then(res => res.json())
      .then(json => {
        this.setState({
          [state]: json,
        })
      });
  }

fetch_data(group1_url, 'group1');

I'd also highly recommend catching errors - possible unhandled rejections should be avoided whenever possible.

You might want to use Promise.all to wait for all groups to load:

const dataSources = {
    group1: 'http://localhost/api/1',
    group2: 'http://localhost/api/2',
    group3: 'http://localhost/api/3',
};
Promise.all(
    Object.entries(dataSources).map(([propertyName, url]) => (
        fetch(url)
            .then(res => res.json())
            .then((result) => {
                this.setState({
                    [propertyName]: result
                })
            })
    ))
)
    .then(() => {
        this.setState({ isLoaded: true })
    })
    .catch((error) => {
        // handle errors
    })

(also note that your json argument is not a JSON - JSON is only a format that exists with strings. Something that has been deserialized is just a plain object or array. Better to call it something less misleading, like result as I did)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, I used your implementation in my code and it worked straight away. It is much cleaner now. I added error handling too.
2

You could try Promise.all

Promise.all takes an array of promises (it technically can be any iterable, but is usually an array) and returns a new promise.

const points = [
    "http://localhost/api/1",
    "http://localhost/api/2",
    "http://localhost/api/3",
];

const responses = await Promise.all(points.map((point) => fetch(point)));
const data = await Promise.all(responses.map((response) => response.json()));
const [group1, group2, group3] = data;

this.setState({
    group1,
    group2,
    group3,
});

Just remember to wrap this logic in an async function

Comments

1

You can do something like this.

function fetch_data(url, state) {
fetch(url)
  .then(res => res.json())
  .then(json => {
    this.setState({
      [state]: json,
    })
  });
}

var group1 = fetch_data(group1_url, 'group1');

Comments

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.