Next.js Discord

Discord Forum

Redoing API requests every 60s

Answered
NanotechPikachu posted this in #help-forum
Open in Discord
Hi.
I have a seperate file named anilist.js which will have my fetch() request code. A small part of the code is like:
import fs from 'node:fs';
import path from 'node:path';
const url = 'https://graphql.anilist.co';

async function trending() {
  const p = path.resolve(process.cwd(), './app/functions/trendingAnime.graphql');
  const query = fs.readFileSync(p, 'utf-8');
  const d = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    },
    body: JSON.stringify({
      query: query
    })
  }).then(res => res.json()).catch(err => console.error(err));
  return d?.data?.Page?.media;
};

I'm importing the functions defined in this file to my page.jsx [It's not client]
What i want is, I wanna do the API call once every 60s or whatever time I wanna it to be. Currently, I just do an
const a = await trending()

Something like this in my page.jsx
How to make it so that it updates regularly in specific time interval without again building it as I host in VERCEL.

I checked docs but it gave me to directly use fetch() in the page.jsx which i wanna avoid if possible. Please help me on how to do this.
Thnx
Answered by joulev
So there are two ways to fix this:

The simpler way is simply adding export const revalidate = 0 to your /more page to make it dynamic. Then every router.refresh() will know the page has already changed and actually make a new request to AniList to refresh your page. But this method makes your page dynamic which means it loads slower.

The slightly more complex way is to use a server action to revalidate your page, and call that server action every x seconds. I have an example here https://github.com/joulev/debug/tree/nextjs-force-refresh-interval
View full answer

43 Replies

@joulev so make a client component with that useEffect and import that client component to your server component page
Well, when I tried converting my page to client, it errored something like "node:fs" etc can't be imported. When i import just "fs" that too said "not found"
Sry for ping. I forgot to turn off mention
I mean importing the functions like trending() to a client page
@NanotechPikachu Well, when I tried converting my page to client, it errored something like "node:fs" etc can't be imported. When i import just "fs" that too said "not found"
No, don’t change your page to client. What you have done is good, no need to change it. Instead just make a new client component with the useEffect above and import it to your page
@NanotechPikachu Sry for ping. I forgot to turn off mention
No worries, in fact please ping if you have questions else I might not know to come answer
something like
function RefreshPageEveryMinute() {
  const router = useRouter();
  useEffect(() => {
    const timeout = setTimeout(() => router.refresh(), 60);
    return () => clearTimeout(timeout);
  }, []);
  return null;
}

and just import it to your page
You mean like
async function M() {
  "use client";
  const a = await trending()
 //Etc
  return ( 
  { /* whatever here */}
  )
}
// Remaining of my code in that page.jsx

Like this?
@NanotechPikachu You mean like js async function M() { "use client"; const a = await trending() //Etc return ( { /* whatever here */} ) } // Remaining of my code in that page.jsx Like this?
that use client won't have any effect.

basically your server component page will look like this
async function Page() {
  const data = await trending();
  ...
  return (
    <>
      ...
      <RefreshPageEveryMinute />
    </>
  )
}
@NanotechPikachu Oh. I see. Okay. Lemme check it Just to `import 'the file path'` and use it as function?
you need to use it as a component otherwise the useEffect call is invalid, since hooks can only be run inside components
Okay. I will check it out
And will reply
The page works and no error is displayed. So, I hope it is working. Can't actually check it cuz I won't know till AniList changes anything in its API.
Thnx for ur help
ur welcome, feel free to ping if it breaks
@joulev ur welcome, feel free to ping if it breaks
Well, .... It is broken lol. the website doesn't update itself even though API response is diff from what's shown in web.
https://anidon.vercel.app/more
If you look into the "LATEST RELEASE" part, the first one hasnt changed though when i manually query the AniList, it should have changed
Okay.... Thnx in advance
If you wanna access to repo, please tell me I will make the repo public
That will help
@NanotechPikachu Sry for the delay https://github.com/NanotechPikachu/Anidon
hmm it looks good to me :chii_think: did the console.log(+) you added show up every 60 seconds?
try adding export const revalidate = 0 to the more/page.jsx file
OH WAIT I KNOW WHY
sorry my bad
it should be setInterval and clearInterval
and the delay is in ms so it should be 60 * 1000
sorry, my brain was lagging when i told you the above
@joulev try adding `export const revalidate = 0` to the `more/page.jsx` file
don't do this yet, just replace setTimeout with setInterval and use 60 * 1000 instead of 60
I have edited it. Lemme check if it updates the AniList API fetch response. From my understanding, the next difference in response of AniList API will be at 12:30 PM IST today. I will confirm and tell you at that time.
Thnx
@joulev don't do this yet, just replace `setTimeout` with `setInterval` and use 60 * 1000 instead of 60
Well, I have tried and the same problem. The page isn't updating itself.
There are console.log() every 60s but update of fetch() isn't happening
ok i think i figured out what is wrong
wait a min
@NanotechPikachu Well, I have tried and the same problem. The page isn't updating itself.
So there are two ways to fix this:

The simpler way is simply adding export const revalidate = 0 to your /more page to make it dynamic. Then every router.refresh() will know the page has already changed and actually make a new request to AniList to refresh your page. But this method makes your page dynamic which means it loads slower.

The slightly more complex way is to use a server action to revalidate your page, and call that server action every x seconds. I have an example here https://github.com/joulev/debug/tree/nextjs-force-refresh-interval
Answer
yes
just need to copy refresh.tsx and refresh-action.ts
Hmm okay. I will check it out after my classes are over. Currently multitasking while watching online class. I will update you after I check it out.
Thx again
@joulev just need to copy refresh.tsx and refresh-action.ts
Thnx bro. It works. As of now, i just have to stay in the page for 60s and it updates itself. But, once people log in more, it will be okay.
That's a small price to pay for salvation
Thnx again.
You’re welcome, have fun coding