javanoob
javanoob

Reputation: 6412

Unable to capture data returned from API call in onSuccess callback

I am using SWR react hook from nextJS with onSuccess callback function but it is not working as I expected. onsuccess callback is invoked but it is not receiving any data.

Here is the minimal code showing the issue:

pages/index.js

import useSWR from "swr";

export default function index() {
  let data = { FirstName: "Default", LastName: "Default" },
    error;
  const fetcher = url =>
    fetch(url).then(r => {
      r.json();
    });
  const [shouldFetch, setShouldFetch] = React.useState(false);
  useSWR(shouldFetch ? "/api/data" : null, fetcher, {
    onSuccess: (data, key, config) => {
      console.log({ data }); //this always prints "undefined"
      this.data = data;
      this.error = error;
    }
  });

  function handleClick() {
    setShouldFetch(true);
  }
  return (
    <>
      <button onClick={e => handleClick()}>Fetch</button>
      Data retrieved from server is: {JSON.stringify(data)}
      Error received from server is: {JSON.stringify(error)}
    </>
  );
}

pages/api/data.js:

export default (req, res) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "application/json");
  res.send({ FirstName: "John", LastName: "Doe" });
};

When I go to localhost:3000/index and click on Fetch button, it still displays FirstName and LasName as "Default".

I think there is something wrong with my onSuccess callback function.

Here is the codesanbdbox demo: https://codesandbox.io/s/nervous-hill-mn0kz?file=/pages/index.js

Upvotes: 0

Views: 4219

Answers (1)

Amal Ajith
Amal Ajith

Reputation: 1012

What you need to do is return the data from the fetcher function

const fetcher = url =>
   fetch(url).then(r => {
   return r.json();
});

Also I would suggest refactoring the code by following best practices. You should ideally be wrapping the following inside a function.

useSWR(shouldFetch ? "/api/data" : null, fetcher, {
   onSuccess: (data, key, config) => {
      console.log({ data }); //this always prints "undefined"
      this.data = data;
      this.error = error;
   }
});

to prevent running it everytime react renders. I would also suggest moving the data into a react state instead of having shouldFetch in state.

Upvotes: 1

Related Questions