Next.js Discord

Discord Forum

Strange behavior with module-defined variables being reset

Answered
Schweizerischer Niederlaufhund posted this in #help-forum
Open in Discord
Schweizerischer NiederlaufhundOP
I feel embarassed posting such a basic question but here goes.

I have a node.js project in which I want to cache a little bit of JSON in memory. I have a .js file like this that will be used by a react component.

let cachedData = null; export const loadData = async () => { cachedData = await fetchTheData(); // this fetches some data async } export const getData = () => { if (cachedData) { // do something } else { console.error("data not there"); } }

I know the loadData is being executed, and it is being invoked only once as planned, long before the call to getData() (ie. no race condition). In fact, I am using instrumentation to load it once like so:

export async function register() { // We use the next.js instrumentation.ts file and the "register" function so that this function gets called // at runtime. It is supposed to run only once, but currently the register api will cause this function to // get invoked twice, once per each next.js runtime. To ensure it gets invoked only once, we will check // the next.js runtime. // For more on this issue, read: https://github.com/vercel/next.js/discussions/50198 if (process.env.NEXT_RUNTIME === 'nodejs') { await loadData(); }

But every time I call getData(), I get the error log.

What gives? It's like next.js is completely reloading my module in between invocations, since cachedData is always null no matter what I do.
Answered by gin
cause after request has finished your memory will be freed
View full answer

28 Replies

@Schweizerischer Niederlaufhund I feel embarassed posting such a basic question but here goes. I have a node.js project in which I want to cache a little bit of JSON in memory. I have a .js file like this that will be used by a react component. `let cachedData = null; export const loadData = async () => { cachedData = await fetchTheData(); // this fetches some data async } export const getData = () => { if (cachedData) { // do something } else { console.error("data not there"); } }` I know the loadData is being executed, and it is being invoked only once as planned, long before the call to getData() (ie. no race condition). In fact, I am using instrumentation to load it once like so: `export async function register() { // We use the next.js instrumentation.ts file and the "register" function so that this function gets called // at runtime. It is supposed to run only once, but currently the register api will cause this function to // get invoked twice, once per each next.js runtime. To ensure it gets invoked only once, we will check // the next.js runtime. // For more on this issue, read: https://github.com/vercel/next.js/discussions/50198 if (process.env.NEXT_RUNTIME === 'nodejs') { await loadData(); }` But every time I call getData(), I get the error log. What gives? It's like next.js is completely reloading my module in between invocations, since cachedData is always null no matter what I do.
this is because data defined with const cant be reassign to a new value, change it to
let cachedData = null;

and try again
Schweizerischer NiederlaufhundOP
my bad.... I didn't copy code because it was a little more complex. I have tried both let and var, no luck, identical behavior.
uhm
so you basically u want it to behave like a class?
and your getData is your getter in this case
and your loadData reloads your cache
u can use loadData() in your getData function if your cachedData is null
so u always ensure the Data returned is not null
cause nextjs isnt really a traditional node app, the environment is designed for the edge so all of your instances u create will eventually get deleted
Schweizerischer NiederlaufhundOP
Thanks for your help. Where can I read about your last sentence please?
Will it make a difference if I use loadData in my getData function? I thought about that but I thought with the behavior I'm experiencing it will just be getting data every time and never setting a cached copy of it...
PS I'm not running in Vercel.... I'm running on aws
cause after request has finished your memory will be freed
Answer
for that reason for example, u can host a socketio server with nextjs
@gin u cant cache data in memory like in a traditional node app
Schweizerischer NiederlaufhundOP
where can I educate myself about this? I haven't seen this explicitly called out in the documentation... since it seems to fly against normal js language semantics I'd like to educate myself about it.
Schweizerischer NiederlaufhundOP
Thanks so much for those resources. But neither seems to inform me that you can't cache data in memory. (Not that there is any doubt given my experience)

As someone new to next.js, I had read the data caching. And I could have made use of it. But as it seemed more complex, I didn't go there.

I think the team at next.js should write a beginner focused article or create a video explaining how and why code such as I have above won't work. Because its not explicitly obvious in the documentation.

As an aside, there are many, many, many github discussions and other posts with developers struggling with this same issue in one way or another.
nextjs rsc functions run on the edge, if u want to behave it like a traditional app u have to use a custom next server
you will loose caching and dynamic features tho
Schweizerischer NiederlaufhundOP
Don't want to argue. Once you know, you know... I mean, having a node.js runtime without behaving like node.js seems complicated to me. And regarding running on the edge... I didn't plan on it, nor configure specifically for it. I'll consult the custom server documentation.
Schweizerischer NiederlaufhundOP
Really appreciate your help! Thanks.
@Schweizerischer Niederlaufhund Really appreciate your help! Thanks.
u can mark my answer as solution :)