File is not defined
My OpenSaas application has a file upload feature where you upload a file and send it to the nodejs backend (as a File object) to read the content, etc. It works fine on my macbook (wasp start), but once published to Railway, when I upload the file, I get the "ReferenceError: File is not defined" error. The line causing the error is "const reconstructedFile = new File([fileBase64], metadata.fileName, { type: metadata.fileType })"
I know that nodeJS doesn't understand the File object, but why does it work when I run it locally (via wasp start), but not on the Railway server? Aren't they both nodeJS environments?
15 Replies
Hi @Kynetix. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To answer your question, I need to clarify a few points and provide some context based on the information available:
1. The File object is indeed not natively available in Node.js environments. It's a Web API that's typically available in browser environments.
2. The fact that it works locally with
wasp start
but not on Railway suggests there might be differences in how the environments are set up or how the code is being executed.
3. When you run wasp start
locally, it's possible that the File object is being made available through a polyfill or some other mechanism that Wasp is providing in development mode.
4. On Railway, which is likely running a production build, this polyfill or mechanism might not be present, leading to the "File is not defined" error.
To address this issue, you have a few options:
1. Use a File polyfill for Node.js environments. There are packages available that provide File-like functionality in Node.js, such as node-file
or file-api
.
2. Instead of using the File constructor, you could create a custom object with the necessary properties and methods to mimic a File object.
3. Modify your server-side code to work with the raw file data instead of trying to reconstruct a File object.
For file uploads in Wasp, you might want to consider using a middleware like Multer, which is commonly used for handling multipart/form-data in Node.js. Here's an example of how you can set up file uploads using Multer in Wasp, based on a gist shared by a Wasp team member:
This approach avoids the need to reconstruct a File object on the server-side and should work consistently across different environments.
Source: Discord support thread (https://discord.com/channels/686873244791210014/1217681705511686194)
Remember to adjust your client-side code accordingly to send the file data in a format compatible with Multer (typically as form-data).
If you need more specific guidance, please provide more details about your current implementation, including relevant parts of your client-side and server-side code.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @Kynetix, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?@Vinny (@Wasp) one for you
So you're calling that function,
new File()
on the backend? If so, try what Kapa suggested:
Use a File polyfill for Node.js environments. There are packages available that provide File-like functionality in Node.js, such as node-file or file-api.
Thanks @Vinny (@Wasp), I'll give it a shot.
Meanwhile, do you have a better way to implement it? The application is a document chatbot where the user uploads a file (Word doc, PDF, XLS, etc) and its content is read and stored in Supabase vector store.
By the way, importing formdata-node solved the File issue.
ok cool, so that was the issue
how did you find out about the
formdata-node
library?Hm but why would that work locally and not once built?
@Kynetix what is our node version taht you use when developing locally? Might be that it is different from the version in Docker that we produce. But still, I doubt File is a new thing hah.
@miho how is it possible that in development we have File availble, but not once deployed to Railway? Coudl taht be connected to bundling we do on the backend in any way?
Following Kapa's suggestion, I googled "node-file" and came across "formdata-node" with some sample code, so I tried it and it worked.
I use node v20.11.1.
Ok, a bit of googling tells me that File was actually added in Node 20!
So you used node 20 locally, and our Docker that we produce uses Node 18.
So one solution is what you did, importing formdata-node, and another solution is to use node 20 in the generated Docker image.
Ah, interesting. So do you plan to implement node 20+ in a future version? (Speaking of, when's the next OpenSaas version coming out? 🙂 )
Since Node.js 20 is the current LTS, we might as well bump Node.js in our Dockerfile 🙂
Yup, that is one thing we can do, and then there is also this: https://github.com/wasp-lang/wasp/issues/1593 -> this would ensure that user specifies node version they want, and then that same version would be used in Dockerfile also. There are also couple of other places (some deps) where it is important.
I'll probably tackle this one first: https://github.com/wasp-lang/wasp/issues/1778
If you want, you can jump on the one you linked, I don't think they exclude each other 🙂
Yeah, they are not really conneted
I'm guessing you guys are the developers of Wasp? Great job guys!!
Yup that is us, you can see by the yellow names (Wasp Team discord role). Thanks a lot :)!!