1

I'm creating a simple GET API that collects data and spits it out as basic text in my front end. The API works and displays the data in console, but nothing is returned for the front end. Please help:

import React, { Component } from 'react';
import './Cards.css'

const data = {
    name: 'test',
    hobby: 'test'
}

function getUsers (data) { 
  fetch('http://localhost:3001/profile', {
    method: 'GET',
    headers: {
    'Content-Type': 'application/json',
    }
  })
  .then((response) => response.json())
  .then((data) => {
    console.log('Success:', data)
  })
  .then((data) => {
    return data.name
  })
  .catch((error) => {
    console.error('Error:', error)
  });
};


function Cards (data) {
  return (
    <div id='cards'>
      <div className="card-header" id='card-header'>
        Header
      </div>
      <div className="card-body" id='card-body'>
        <blockquote className="blockquote mb-0">
          <p>
            {getUsers(data)}
          </p>
          <footer className="blockquote-footer">Someone famous in <cite title="Source Title">Source Title</cite></footer>
        </blockquote>
      </div>
    </div>
  );
}


export default Cards;

2
  • 2
    getUsers is async, so you will need to use state for updating. Although things like this should be easier when suspense is live -> reactjs.org/docs/concurrent-mode-suspense.html Commented Mar 2, 2020 at 10:26
  • Also, in your second .then you console.log the data but don't return it, so it'll be lost and won't be passed to the next .then Commented Mar 2, 2020 at 10:29

3 Answers 3

1

The right way to address this is to fetch data from API (you can trigger the call through the useEffect hook), store the result in your component's state and then use this state value in your JSX.

import React, { useState, useEffect } from "react";
import "./Cards.css";

const data = {
  name: "test",
  hobby: "test"
};

function Cards(data) {
  const [name, setName] = useState("")

  useEffect(() => {
    getUsers()
  }, [getUsers])

  function getUsers(data) {
    fetch("http://localhost:3001/profile", {
      method: "GET",
      headers: {
        "Content-Type": "application/json"
      }
    })
      .then(response => response.json())
      .then(data => {
        console.log("Success:", data);
      })
      .then(data => {
        setName(data.name)
        return data.name;
      })
      .catch(error => {
        console.error("Error:", error);
      });
  }
  return (
    <div id="cards">
      <div className="card-header" id="card-header">
        Header
      </div>
      <div className="card-body" id="card-body">
        <blockquote className="blockquote mb-0">
          <p>{name}</p>
          <footer className="blockquote-footer">
            Someone famous in <cite title="Source Title">Source Title</cite>
          </footer>
        </blockquote>
      </div>
    </div>
  );
}

export default Cards;

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

4 Comments

Thank you! And everyone else who commented. This is a huge help!
I'm still getting a similar error when using the above code. I researched it and I think I understand this now, but I can't figure out what is causing the error still. WIthout tweaking anything, the above code gives me the following error: "Cards.js:25 Success: {name: "Griffin", hobby: "Dota 2"} Error: TypeError: Cannot read property 'name' of undefined at Cards.js:28 Cards.js:25 Success: {name: "Griffin", hobby: "Dota 2"} index.js:1 Error: TypeError: Cannot read property 'name' of undefined at Cards.js:28"
When I replace setName(data.name) with setName('Griffin') it works? So the set state is working. If I console.log(data.name); I get exactly what I need, but it just refuses to spit the data into the paragraph? it's the data variable within the API that's causing this.
This seems to mean that data is undefined. Does it work if you call setName in the previous then block. (The one where you log "Success")
0

i think that you should return the data if you are chaining another .then afterwards, it makes sense that the first then is console logging the data properly but the second gets no return.

.then((data) => {
  console.log('Success:', data)
    [should be a 'return data' here?]
})
.then((data) => {
  return data.name
})

and also your function is async, so it should be inside a useEffect callback.

Comments

0

You can use useEffectand state as explained in comments, the code below should work:

import React, { Component, useEffect } from 'react';
import './Cards.css'

const data = {
    name: 'test',
    hobby: 'test'
}






function Cards (data) {
    const [ users, setUsers] = useEffect('')
    useEffect(() => {
        function getUsers (data) { 
            return fetch('http://localhost:3001/profile', {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                }
            }).then((response) => response.json())
            .catch((error) => {
                console.error('Error:', error)
            });
        };
        getUsers(data).then((data) => setUsers(data.name) )
    }, [])
    return (

        <div id='cards'>

            <div className="card-header" id='card-header'>
                Header
            </div>
            <div className="card-body" id='card-body'>
            <blockquote className="blockquote mb-0">
            <p>
            {users}
            </p>
            <footer className="blockquote-footer">Someone famous in <cite title="Source Title">Source Title</cite></footer>
            </blockquote>
            </div>
        </div>

    );}


export default Cards;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.