3

I am trying to make an API call in React to return JSON data but I am a bit confused on how to go about this. My API code, in a file API.js, looks like this:

import mockRequests from './requests.json'

export const getRequestsSync = () => mockRequests

export const getRequests = () =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(mockRequests), 500)
})

It is retrieving JSON data formatted like this:

{
"id": 1,
"title": "Request from Nancy",
"updated_at": "2015-08-15 12:27:01 -0600",
"created_at": "2015-08-12 08:27:01 -0600",
"status": "Denied"
 }

Currently my code to make the API call looks like this:

import React from 'react'

const API = './Api.js'

const Requests = () => ''

export default Requests

I've looked at several examples and am still a bit confused by how to go about this. If anyone could point me in the right direction, it would be greatly appreciated.

EDIT: In most examples I've seen, fetch looks like the best way to go about it, though I'm struggling with the syntax

3 Answers 3

4

Here is a simple example using a live API (https://randomuser.me/)... It returns an array of objects like in your example:

import React from 'react';

class App extends React.Component {
  state = { people: [], isLoading: true, error: null };

  async componentDidMount() {
    try {
      const response = await fetch('https://randomuser.me/api/');
      const data = await response.json();
      this.setState({ people: data.results, isLoading: false });

    } catch (error) {
      this.setState({ error: error.message, isLoading: false });
    }
  }

  renderPerson = () => {
    const { people, isLoading, error } = this.state;

    if (error) {
      return <div>{error}</div>;
    }

    if (isLoading) {
      return <div>Loading...</div>;
    }

    return people.map(person => (
      <div key={person.id.value}>
        <img src={person.picture.medium} alt="avatar" />
        <p>First Name: {person.name.first}</p>
        <p> Last Name: {person.name.last}</p>
      </div>
    ));
  };

  render() {
    return <div>{this.renderPerson()}</div>;
  }
}

export default App;

Does it make sense? Should be pretty straight forward...

Live Demo Here: https://jsfiddle.net/o2gwap6b/

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

4 Comments

Thanks, this really helps me get a grasp on the whole thing
The one thing I'm still struggling with is fetching from a local file, in this case Api.js as shown in my original post, if I change the fetch to '.Api.js' or './requests.json' I get an error saying unexpected token < in JSON at position 0 which means its getting HTML code instead of JSON
That's not the issue and I can't really tell from the code you have up... Maybe make a github repo with the full code and post the link here...
but what if i am not writing api call in Didmount. how to work with loader if i have a special action pages. also i dont want to use dispatch to send a flag to stop the loader. what i am looking for is to stop loader as soon as i get response from api
3

You will want to do something like this:

var url = 'https://myAPI.example.com/myData';
fetch(url).then((response) => response.json())
          .then(function(data) { /* do stuff with your JSON data */})
          .catch((error) => console.log(error));

Mozilla has extremely good documentation on using fetch here that I highly recommend you read.

The data parameter in the second .then will be an object parsed from the JSON response you got and you can access properties on it by just using the property label as was in the JSON. For example data.title would be "Request from Nancy".

3 Comments

Could you give an example of what would be in the do stuff with your JSON data area?
SakoBu's answer is a good example. In their code the second .then callback is mapping the JSON object to the component's state (the variable is called response instead of data but it is the same). Basically you would typically either assign the data to another variable with greater scope or call a function to save the data somewhere.
but what if i am not writing api call in Didmount. how to work with loader if i have a special action pages. also i dont want to use dispatch to send a flag to stop the loader. what i am looking for is to stop loader as soon as i get response from api
3

If you are struggling with fetch, Axios has a much simpler API to work with.

Try this in your API.js file (of course install axios first with npm i --save axios):

import axios from 'axios'
import mockRequests from './requests.json'

export const getRequests = (url) => {
  if (url) {
    return axios.get(url).then(res => res.data)
  }

  return new Promise((resolve, reject) => { // you need to return the promise
    setTimeout(() => resolve(mockRequests), 500)
  })
})

In your component, you can access the getRequests function like so

import React, { Component } from 'react'
import { getRequests } from './API.js'

class App extends Component {
  state = { 
    data: null
  }

  componentWillMount() {
    getRequests('http://somedomain.com/coolstuff.json').then(data => {
      console.log(data)
      this.setState({ data })
    })
  }

  render() {
    if (!this.state.data) return null

    return (
      <div className='App'>
        {this.state.data.title}
      </div>
    )
  }
}

export default App

1 Comment

but what if i am not writing api call in Didmount. how to work with loader if i have a special action pages. also i dont want to use dispatch to send a flag to stop the loader. what i am looking for is to stop loader as soon as i get response from api

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.