Next.js Discord

Discord Forum

Not quite understanding how API / refreshing works.

Answered
Abyssinian posted this in #help-forum
Open in Discord
AbyssinianOP
Hello, all. I'm brand new to Next and having a bit of trouble wrapping my mind about how things work. I'll describe my problem as best I can, sorry for the wall of text.

So, I'm building a very basic app that has server pages and an API. I haven't yet set up a database, so the API just has static data that it sends. So far I have a single point: /api/user/id which sends a user object. The route looks like this:

export async function GET(request: Request, { params }: { params: { id: string } }) {
  const id = params.id;
  const user: TUser = userResolver(id); // this is just a JS object
  // Here I am just trying to see if anything at all changes when I expect a refresh. No luck so far.
  user.inventory[1].amount = Math.floor(Math.random() * 10);
  return NextResponse.json(user);
}

Components-wise, I have a User, Inventory, InventoryItem server components, and a Toggle client component. The User component makes the API call and gets the user. It then passes the user data to the Inventory component. That one does some formatting of the inventory items. The InventoryItem page displays the formatted item and the Toggle.

Now, the items are going to be changed on the fly, so I am trying to see how that would work. This is my Toggle component:

const EquippedToggle = ({ equipped }: TEquippedToggle) => {
  const [isEquipped, setIsEquipped] = useState(equipped);

  const router = useRouter();

  const handleToggle = () => {
    setIsEquipped(!isEquipped);
    // Fetch call to update the database will eventually go here.
    router.refresh(); // Now just trying to see if refresh will fetch different data.
  };

  return <input type="checkbox" checked={isEquipped} onChange={handleToggle} />;
};

When I check/uncheck the input, a GET request goes out, but nothing updates. I am sure I am doing something wrong or simply not understanding what to expect. Could someone please help and explain?

Thank you!
Answered by Abyssinian
Just so that I can mark this as "answered": The solution was to stop using Turbopack and then add a { cache: "no-cache" } to the fetch call.
View full answer

36 Replies

AbyssinianOP
Nobody knows? 😢
European sprat
If you aren't changing anything with the API, why would you expect something to be different when the GET request is sent?
AbyssinianOP
Well, that's the thing, I am changing something. I would expect a different user.inventory[1].amount every time a GET request is made to the API.
AbyssinianOP
Maybe I'm all kinds of confused about the whole server vs. client component thing. Perhaps an Item should be a client component instead of a server component, because its contents change? For some reason in my head it was that only the interactive element (such as a checkbox) needs to be a client component. Am I wrong?
European sprat
Oh sorry I missed that you had math random in the API request. If you add a console log to the GET function, does the log show in the server output when you hit the API?
AbyssinianOP
Yes, the very first time it goes log it. But then it's just the GETs.
The "AAA" is the console log, with 2 being the random number.
European sprat
I could be wrong but it might be statically rendering that route https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic-rendering
Try export const dynamic = "force-dynamic"
In the API route
AbyssinianOP
So this would go to app/api/user/[id]/route.ts?
Hmm... this doesn't appear to change anything.
AbyssinianOP
I switched from Turbopack to whatever's default (Webpack?) and now I see a bit of a difference.
So if I just reload the page or check/unckeck the checkbox, then I see this:
However, if I reload with Ctrl+Shift+R, I see this:
OMG! I had to add { cache: "no-cache" } to
const response = await fetch(`http://localhost:3000/api/character/${characterId}`, { cache: "no-cache" });
And now it works exactly as I'd expect! The thing is, I even tried it before, but because I was using Turbopack it had no effect.
I also ended up not not needing export const dynamic = "force-dynamic";
European sprat
Glad to hear you got it working!
AbyssinianOP
Thank you for your help! 🙂
@Abyssinian And now it works exactly as I'd expect! The thing is, I even tried it before, but because I was using Turbopack it had no effect.
American Crocodile
Could you try to check if it works in production as well? I'm running into a similar issue as yours.. works fine in development, but my get request seems to have stale cached data in production...
American Crocodile
you do npm run build followed by npm run start
tyty
I'm curious to see
AbyssinianOP
Can't build, getting errors. Will let you know once I'm able to.
American Crocodile
okay no worries, pls ping me when you get the chance to build
@American Crocodile okay no worries, pls ping me when you get the chance to build
AbyssinianOP
I was able to build it despite having some type errors. When running a prod build, everything works the same as in the dev build. So it's all good.
The errors look like this:
American Crocodile
ah okay, dang I might be doing something wrong then... thank you
AbyssinianOP
Glad to help!
@Abyssinian Glad to help!
American Crocodile
update on this, I switched from app directory nextjs to pages nextjs and it resolved my problems
no idea why but it worked when I switched
AbyssinianOP
Yeah, stuff is pretty weird with Next. I'm now having doubts about learning it.
AbyssinianOP
Just so that I can mark this as "answered": The solution was to stop using Turbopack and then add a { cache: "no-cache" } to the fetch call.
Answer