In a basic Remix V2 app, i need help understanding if the following is expected behavior, a bug in V2, or possibly a missing configuration option or setting.
When running in development mode via npx run dev
i am seeing the useLoaderData
hook receive a JavaScript object declaration as its value as opposed to JSON.
I could not find anything related to this issue in the Remix documentation.
Full details to reproduce the issue:
I created an demo Remix V2 app by running npx create-remix@latest
I wrote a simulated API backend method stored in app/api/notes.ts
which has one method that returns JSON data that it loads from a JSON file that i have stored at the root of my application ./app/notes.json
:
import fs from 'fs/promises';
...
export async function getStoredNotes() {
const rawFileContent = await fs.readFile('notes.json', { encoding: 'utf-8' });
const data = JSON.parse(rawFileContent);
const storedNotes = data.notes ?? [];
return storedNotes;
}
The client side consists of 2 simple routes, index
and notes
and i have defined 2 NavLink
components for navigation:
import { NavLink } from '@remix-run/react';
...
<NavLink to="/">Home</NavLink>
<NavLink to="/notes">Notes</NavLink>
In the notes
route, i have the following loader
function defined which makes a call to my simulated API method:
import { getStoredNotes } from '~/api/notes';
...
export const loader:LoaderFunction = async () => {
try {
const notes = await getStoredNotes();
return json(notes);
} catch (error) {
return json({ errorMessage: 'Failed to retrieve stored notes.', errorDetails: error }, { status: 400 });
}
}
In the notes
main component function i receive that data using the useLoaderData
hook and attempt to print the returned JSON data to the console:
export default function NotesView() {
const notes = useLoaderData<typeof loader>();
console.log(notes);
return (
<main>
<NoteList notes={notes as Note[] || []} />
</main>
)
}
When i run an npx run build
and subsequently npx run serve
everything is working correctly:
Initial page load receives the data successfully and prints the value to the console as JSON.
{"notes":[{"title":"my title","content":"my note","id":"2024-03-28T05:22:52.875Z"}]}
Subsequent navigation client side between the index
and notes
routes via the NavLink
components is also working correctly such that i see the same data print to the console.
The problem arises when i run in development mode via npx run dev
as follows:
The initial page load coming from the server does load correctly and prints the JSON to the console as expected, however:
Subsequent navigation client side between the index
and notes
routes using the NavLink
components does not print the JSON data to the console. Instead, i am seeing a JavaScript object declaration print to the console quite literally just like this:
export const notes = [
{
title: "my title",
content: "my note",
id: "2024-03-28T05:22:52.875Z"
}
];
Is this expected behavior when running in dev
mode?
What can i do to troubleshoot this issue?
2
Answers
I want to credit @Kiliman for leading me in the right direction in-order to figure out what was causing the odd behavior.
I assume this is not a bug at all but rather a bad implementation on my part in attempting to quickly test a hello world example of a Remix app.
It was the location of my
notes.json
file that was the issue.To replicate the behavior where JSON retrieved from a file is returned as a JavaScript object declaration, the source
notes.json
file would need to sit at the root of the project folder itself. So, not in./app/notes.json
but rather./notes.json
such that it sits in the same directory as thepackage.json
file.This was likely a mistake to begin with as i assume we should never store any asset at the root of the project folder.
i created this StackBlitz example to demonstrate the behavior.
Hmmm… I’m not sure why you’re getting those results. You definitely shouldn’t get ‘code’ from
useLoaderData
.Here’s a ⚡️ StackBlitz showing that it works properly. If you still have issues, can you post a simple repo showing the error?
https://stackblitz.com/edit/remix-run-remix-xhfw3r?file=app%2Froutes%2Fnotes.tsx