FAQ: The Effect Hook - Fetch Data

This community-built FAQ covers the “Fetch Data” exercise from the lesson “The Effect Hook”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Learn React

FAQs on the exercise Fetch Data

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!
You can also find further discussion and get answers to your questions over in Language Help.

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head to Language Help and Tips and Resources. If you are wanting feedback or inspiration for a project, check out Projects.

Looking for motivation to keep learning? Join our wider discussions in Community

Learn more about how to use this guide.

Found a bug? Report it online, or post in Bug Reporting

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

I can’t seem to make heads or tails of this exercise, and I’m not sure if what’s happening is a bug with Codecademy’s assignment-completion system or some erroneous code on my behalf.

As soon as I get to Step 2, setData([response.data]); it appears that the whole thing crashes. Am I supposed to be inserting this section into the useEffect() hook? If so, why is it that calling setData() seemingly fails to update my data state, thereby preventing me from rendering the JSX portion of the exercise?

I can’t get much else to show up past the <p>Loading...</p> display. And confusingly, even though I can’t seem to get it to work, the system lets me continue to the next part of the exercise although it seems like I haven’t done the previous bit correctly…!

4 Likes

Are you inserting setData after the first or second alert?

Mine is structured as follows:

      alert('Response: ' + JSON.stringify(response,'',2));
      setData(response.data);

And its worked for me.

Below is what the useEffect looks like at the end of the lesson:

 useEffect(() => {
    alert('Requested data from server...');
    get(forecastType).then((response) => {
      alert('Response: ' + JSON.stringify(response,'',2));
      setData(response.data);
    });
  }, [forecastType]);

3.

Type in each of the notes’ input fields in our table. What do you notice? Why do you think this is happening?

Each time that we type in an input field, the component re-renders to show the new value of that field. Even though we don’t need any new data from the backend, our component is fetching new data after every render!

Use an empty dependency array to ensure that data is only fetched after our component’s first render.

I don’t see any rendered HTML in the http://localhost:8000/

I see no table or no opportunity to type in notes

return (


My Weather Planner



<button onClick={() => setForecastType(’/daily’)}>5-day
<button onClick={() => setForecastType(’/hourly’)}>Today











{data.map((item, i) => (






))}

Summary Avg Temp Precip Notes
{item.summary} {item.temp.avg}°F {item.precip}%
<input
value={notes[item.id] || ‘’}
onChange={handleChange(item.id)}
/>


);

Is it just me or are there several typos in this code that comes loaded on this lesson?
tbody?
thead?

Why am I not seeing any HTML elements?

The same issue is happening to me, i dont see any loaded html. my screen just proceeds to have a “loading…” text in it. at step 3 there was never any text inputs or buttons to click in the rendered html area More bugs? Did you figure out what was wrong?

1 Like

What do I do in step 4? I don’t get it

Step 1 of the task is simple. My solution works, but the platform marks it as wrong. The source code of the stored solution is identical to the source code of the task.
What could be the problem?

3 Likes

Did you figure this out? I am having the same problem: my solution works, and is the same as what is given in the hint, but the platform marks it as wrong.

Hi, It looks like I am in the same boat as you. Wonder if there is a way to reach the experts in Codecademy, those who wrote this lesson on ‘Fetch Data’ in ReactJS? Something is wrong in the sand box coding, I presume. The error reported is as follows,

“Oops! The test returned an error. Maybe you have a syntax error, or a typo. Hide error.”
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db

Why you should do it regularly:

{
“stats”: {
“suites”: 0,
“tests”: 1,
“passes”: 1,
“pending”: 0,
“failures”: 0,
“start”: “2021-07-25T22:51:51.814Z”,
“end”: “2021-07-25T22:51:52.149Z”,
“duration”: 335
},
“tests”: [
{
“title”: “”,
“fullTitle”: " ",
“duration”: 331,
“currentRetry”: 0,
“err”: {}
}
],
“pending”: ,
“failures”: ,
“passes”: [
{
“title”: “”,
“fullTitle”: " ",
“duration”: 331,
“currentRetry”: 0,
“err”: {}
}
]
}

1 Like

Does someone has an cheatsheet that I can take advantage of? Im struggling with this topic

OH thank goodness!!! The strugs with this are real… I’m struggling with step 3 and I get for some reason two cycles of the weather alerts…and not that it matters but I followed the directions to the best of my abilities… It would be cool if the solution code showed you the solution in increments instead of the whole thing. I’d like to see what my own glitch is in comprehension. :upside_down_face:

3 Likes

Which browser are you using? I have the same issue.

If you open the solution (I was forced to do it as nothing appears on the screen) you’ll find out it looks so differently from the code you have from the very beginning and no wording or instructions didn’t even try to explain that you need to modify those code snippets. Does anybody on the Codecademy cares that people are dealing with the same issues for YEARS reporting bugs but they change nothing? I’m so disappointed as these bugs appear almost each lesson since JS lessons

3 Likes

Some of the tests seemed messed up on this page (and others in this module). I’m including the code I had for this exercise as I couldn’t even figure out how to get the solution to display.

For Step 1, add this code before the return at the end of the function:

  if (!data) {
    return (
      <p>Loading...</p>
    )
  }

This ensures that we don’t try to iterate over an undefined data variable.

For Step 2, I added this code:

    get(forecastType).then((response) => {
      setData(response.data);
      //alert('Response: ' + JSON.stringify(response,'',2));
    });

Interestingly, we were told previously that the proper way to use setData is to provide a function like (prev) => response.data. However, that does not pass the tests. I’m also unclear on when we should wrap the right side of the arrow in parentheses or braces. Those things seem to trip up tests elsewhere in this module as well.

For Step 3, add the empty dependency array to the useEffect call to prevent re-fetching on all renders of this component. Ah, but then realize that we do want to re-fetch if the forecastType changes, ending up with:

  useEffect(() => {
...
  }, [forecastType]);

For Step 4, I found that the logical answer /{forecastType} didn’t work, but plain forecastType did. I’m not sure why the slash would disappear.

Here’s my complete answer. I hope this helps!

import React, { useState, useEffect } from "react";
import { get } from './mockBackend/fetch';

export default function Forecast() {
  const [data, setData] = useState();
  const [notes, setNotes] = useState({});
  const [forecastType, setForecastType] = useState('/daily');

  useEffect(() => {
    alert('Requested data from server...');
    get(forecastType).then((response) => {
      setData(response.data);
      //alert('Response: ' + JSON.stringify(response,'',2));
    });
  }, [forecastType]);

  const handleChange = (index) => ({ target }) =>
    setNotes((prev) => ({
      ...prev,
      [index]: target.value
    }));

  if (!data) {
    return (
      <p>Loading...</p>
    )
  }
  return (
    <div className='App'>
      <h1>My Weather Planner</h1>
      <div>
        <button onClick={() => setForecastType('/daily')}>5-day</button>
        <button onClick={() => setForecastType('/hourly')}>Today</button>
      </div>
      <table>
        <thead>
          <tr>
            <th>Summary</th>
            <th>Avg Temp</th>
            <th>Precip</th>
            <th>Notes</th>
          </tr>
        </thead>
        <tbody>
          {data.map((item, i) => (
            <tr key={item.id}>
              <td>{item.summary}</td>
              <td> {item.temp.avg}°F</td>
              <td>{item.precip}%</td>
              <td>
                <input
                  value={notes[item.id] || ''}
                  onChange={handleChange(item.id)}
                />
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}
1 Like

hi, just want to report a bug:

the test for this part of the lesson really doesn’t seem to like comments after the useEffect() function. i was getting real confused on why the lesson didn’t like me doing exactly what i was told to do (in this case, pass an empty dependency array into useEffect() ) until i removed a comment after the function explaining what it does.

it ended up doing this again for the forecastType step, where i re-added the comment and it acted as if i didn’t do the step at all.

This entire course needs to be removed and reworked. When you pay for this, you expect this to work and make sense. It does neither. I have been here for years and my renewal is next month and seriously thinking of taking my money elsewhere.

7 Likes

Thanks for the detailed response! Adding my own journey on this exercise in case it helps someone else. For Step 1 I created an if statement above the return to create a variable and set it equal to the content I want to render. In this way, I’m still showing the headers and returning all of the table information except the content created by the data.map. However, once data !== undefined, the map function results will display. However, the value was stuck on loading since there isn’t any code in the exercise at this point to update the value of data. Hence step 2! This may not be the most elegant solution, but I’d love to see examples to improve it!

if (data === undefined) {
      objData = <p>Loading...</p>;
    } else {
      objData = (data.map((item, i) => (
            <tr key={item.id}>
              <td>{item.summary}</td>
              <td> {item.temp.avg}°F</td>
              <td>{item.precip}%</td>
              <td>
                <input
                  value={notes[item.id] || ''}
                  onChange={handleChange(item.id)}
                />
              </td>
            </tr>
          )));

Step 2: My first step was to try to understand the format of the response object being returned by get(). I alerted this to the screen to see that response.data is the array I’m looking for as the provided code in the map() function referenced .id, .summary, .temp.avg… etc. All of which appeared to exist in the correct format in response.data. Therefore I merely added the following to the useEffect formula. I found the double alert annoying so I removed one of them so I still knew when the useEffect() was being called.

setData(response.data);

Step 3: Every time I typed, that annoying alert popped up so I could tell that typing had the effect of re-rendering the DOM triggering useEffect(). Adding an empty array to the second argument of useEffect causes useEffect to only trigger upon mount so typing no longer triggered it to update. This is the desired outcome… unless we want it to trigger at some other point??

useEffect(() => {
    get(forecastType).then((response) => {
      alert('Fetching new data');
      setData(response.data);

    });
  }, []);

Step 4: Alas, we do want new data if and when we change the forecastType. The buttons already have an appropriate onClick call to setForecast so I really just need useEffect, which calls for new data and stores it, to trigger whenever forecastType changes. Adding the variable name ‘forecastType’ to the previously empty dependency array tells useEffect to trigger upon a change to this specific variable and does the trick! The reason why you don’t need a slash is because you aren’t referencing a string here, you are referencing the variable forecastType. setForecastType() (the function that updates the variable forecastType with whatever parameter you provide it) is already updating the variable to the string “/daily” or “/hourly” when it’s called upon the button click as shown below. So adding a slash is not required.

<button onClick={() => setForecastType('/daily')}>5-day</button>
<button onClick={() => setForecastType('/hourly')}>Today</button>
 useEffect(() => {
    get(forecastType).then((response) => {
      alert('Fetching new data');
      setData(response.data);
    });
  }, [forecastType]);

I had to think through this exercise for a while. At the end, I didn’t run into any bugs but I had to understand what the designers of this exercise were trying to demonstrate. Others have reported bugs in this module, but perhaps Codecademy fixed it?

I can confirm that I do not have this issue as of the time of this writing. Perhaps it is fixed?

Is there a way to only make the API call once instead of having to fetch it every time a different button is pressed?

First thing that comes to mind is to use two separate useEffect hooks. One using an empty array dependancy to fetch the data, and one to use the forecastType state variable to toggle the UI depending on which button is pressed.

I really had a bad UX on Fetch Data.
First, alert is very annoying, while I was trying to make every answers.
Second, I don’t know why setData(prev=>response.data) does not work.