Consider a Remix route with a form that uploads a file using enctype='multipart/form-data'. What does Remix do with the uploaded file data in the action function?
export const action = async ({ request }) => { const formData = await request.formData(); const file = formData.get('file'); // What is the type of 'file' here? return null; };
Think about how formData.get() works with file inputs in web APIs.
In Remix, when you get a file input from formData.get(), it returns a File object. This object lets you access the file's stream or read its content without loading everything into memory at once.
You want to save an uploaded file to disk inside an action function in Remix. Which code snippet correctly streams the file to a local path?
export const action = async ({ request }) => { const formData = await request.formData(); const file = formData.get('file'); // Save file to disk here };
Remember that pipe returns the destination stream, and you need to wait for the stream to finish writing.
To properly stream a file to disk, you pipe the file's stream to a writable stream and await a promise that resolves when the 'finish' event fires. Option C correctly wraps this in a Promise and awaits it.
Review the following action function code snippet. Why might it cause a memory leak when uploading large files?
export const action = async ({ request }) => { const formData = await request.formData(); const file = formData.get('file'); const buffer = await file.arrayBuffer(); await fs.promises.writeFile('./uploads/' + file.name, Buffer.from(buffer)); return null; };
Consider how large files are handled in memory when using arrayBuffer().
Using arrayBuffer() loads the entire file content into memory at once. For large files, this can cause high memory usage or leaks. Streaming the file is better for large uploads.
Which statement best describes how Remix's file upload handling differs from a typical Express.js app using multer middleware?
Think about the web platform APIs Remix builds on compared to Node.js middleware.
Remix uses the native web Request and formData() APIs, allowing direct access to file streams without extra middleware. Express apps typically need middleware like multer to parse multipart form data.
Given the following Remix loader function that streams a text response, what will the client receive?
export const loader = () => {
const stream = new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode('Hello '));
setTimeout(() => {
controller.enqueue(new TextEncoder().encode('World!'));
controller.close();
}, 100);
}
});
return new Response(stream, { headers: { 'Content-Type': 'text/plain' } });
};Consider how ReadableStream and controller.enqueue work asynchronously.
The stream first sends 'Hello ' immediately, then after 100ms it sends 'World!' and closes. The client receives the full concatenated string as a streamed response.