1

So I`m trying to create a service to be used in the entire project which makes an API call to retrieve some data from the server. The function looks something like this

export function data(){
  const proxyurl = "https://cors-anywhere.herokuapp.com/";
  fetch(proxyurl+process.env.REACT_APP_TEXT_API)
    .then(res => res.json())
    .then(json => {
     return json;
    })
}

I`m trying to access the returned json in my React component by doing this

import {data} from '../../../../services/textService/textApi'



class Error404Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: "Something"
    }
  }

   componentDidMount() {
   this.setState({
     data: this.data()
   })

  }

The problem is the state variable "data" value is set to undefined. How can I access the data returned by my function?

Vencovsky
  • 28,550
  • 17
  • 109
  • 176
Octavian
  • 623
  • 2
  • 6
  • 17
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – hindmost Sep 11 '19 at 13:34
  • You can't directly get response in your component. You need to first connect your react component with Redux store. Use "react-redux" plugin for this. – Sudarshan Tanwar Sep 11 '19 at 13:37
  • What?? Why do you need react-redux for that? It will work just fine. I think you also need to check the solutions to understand. – Praneeth Paruchuri Sep 11 '19 at 13:46

2 Answers2

1

JavaScript functions that are expected to return something must explicitly return them. Here's an example of the original post's code that returns the promise. I've thrown the function call into a Hook, but the same thing could be accomplished in a class-based component.

import React, {useEffect} from "react";
import ReactDOM from "react-dom";

function data(){
  return fetch('https://jsonplaceholder.typicode.com/todos/1')
    .then(res => res.json())
    .then(json => json)
}

function App() {
  useEffect(() => {
    data().then(resp => console.log(resp))
  })

  return (
    <div />
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

This will log the response of our sample API endpoint to the console when App mounts.

Returning Promise Demo (Code Sandbox)

Jake Worth
  • 5,490
  • 1
  • 25
  • 35
  • I need to be able to import this service outside of a render function, that's why I'm using a function and not a class. – Octavian Sep 11 '19 at 13:47
  • In this answer, `data` is not inside a `render` function. It is separate from the component and could be imported from anywhere. – Jake Worth Sep 11 '19 at 13:51
  • Can you show me an example of how you will import this in a class? – Octavian Sep 11 '19 at 13:54
  • Importing or using classes is not why the OP's code was failing. Take it one step at a time: put the function in the same file as the component, then figure out how to return the promise and call the function in your `componentDidMount`. Set state in the promise return. Then move the function into your API file. – Jake Worth Sep 11 '19 at 14:28
0

You forgot to return the fetch.

export function data(){
  const proxyurl = "https://cors-anywhere.herokuapp.com/";
  // added return statement
  return fetch(proxyurl+process.env.REACT_APP_TEXT_API)
    .then(res => res.json())
    .then(json => {
     return json;
    })
}

But this will also have some problems, you need to use await/async or .then.

async componentDidMount() {
   // using await / async 
   const newData = await data()
   this.setState({
     data: newData
   })
}

If you want to call data that comes from import {data} from '...', you don't use this.data(). this will be from your component, not from the import.

Vencovsky
  • 28,550
  • 17
  • 109
  • 176
  • I've just tried your solution and I get an error saying that data is not a function when i do const data = await data(). – Octavian Sep 11 '19 at 13:42
  • @Octavian Please make sure that you are importing `data` the correct way. If you aren't, `data` will be undefined and will give you that error – Vencovsky Sep 11 '19 at 13:43
  • @Octavian Also, just made a edit, had a small error there, please try it out. – Vencovsky Sep 11 '19 at 13:45