This is the best tutorial I have found for reactjs and nodemailer. Thank you for this.
I went through the comments and I saw that you did a followup for someone with react-hook-form. I also am using react-hook-form, and it helped me adapt to my code. However, I am attempting to use my form to send files through nodemailer. No matter where I look, I cannot find any information on getting the file data from react-hook-form into nodemailer. Would you happen to have any insight on this?
Hey not sure if you've already figured out the react portion of this question but with react-hook-form and files, all you'd have to do is add an input like this to your form:
<input type="file" {...register("file")} />
If you throw a console.log of the data in your onSubmit, you should see the file info there. I'll follow up later on the nodemailer side!
I have that part figured out already. I can get the data to my API, but what I can't figure out is how to make the 'file' attach with nodemailer. In my browser I see the file being sent like this:
"documentsUpload: FileList
0: File {name: 'Email Attachment test.txt', lastModified: 1647400270450, lastModifiedDate: Tue Mar 15 2022 22:11:10 GMT-0500 (Central Daylight Time), webkitRelativePath: '', size: 20, …}
length: 1"
But the data sent is blank:
"documentsUpload: { '0': {} }"
And nothing comes through on the email attachments.
Yeah I'm actually running into the same thing. I can see the file updating when I log it but when I send it, it goes through blank. Not super sure why that's happening yet. I'm going to try and see If throwing together a custom onChange for this file input helps. Not sure what's happening in the background of react-hook-form with sending files.
constfileUpload=require("express-fileupload");// I don't know whyapp.use(express.urlencoded({extended:true}));// But this is required. I dropped itapp.use(fileUpload({createParentPath:true// and it stopped working.}));constsendEmail=async(data)=>{letform=document.querySelector('form');constformData=newFormData(form);const{file}=data;for(let[index,value]ofObject.entries(file)){formData.append(value.name,file[index]);}axios({method:'post',url:'http://localhost:3001/send',data:formData,});}
and on the backend:
app.post('/send',async(req,res)=>{constdocs=Object.keys(req.files).map(key=>{return{filename:req.files[key].name,content:req.files[key].data}});letmailOptions={from:'whoever@whereever.net',to:'to-mail@mail.go',subject:`Message from: Whoever`,html:'<html></html>',attachments:docs// <--- All you need here!!};transporter.sendMail(mailOptions,function(err,data){if(err){res.json({status:'fail',});}else{console.log('== Message Sent ==');res.json({status:'success',});}});});
I edited it a dozen times to make sure I had it just right, for posterity. I really hope this helps someone later, because it was a pain to figure out, and searching yielded bits and pieces, but NOTHING on the backend portion.
Yeah it definitely will. I had a hard time finding quality full stack nodemailer stuff before putting this article together with bits and pieces that I found that worked. What really surprised me is how you were able to receive the file data on the api without needing a middleware package like multer. I’ll for sure be trying this.
Hey, really happy to hear that this helped you! This gets a little more complex and I'll definitely expand on this specific question with react-hook-form when I get a little more time.
Until then, these resources may help:
You will most likely have to use FormData() to handling attaching a file on the frontend.
Didn't test these comments but this stackoverflow article about FormData & react looks promising on how to do it with a handleChange or handleSubmit function.
On the backend, you will will have to at least use a library like multer to handle those file requests.
I know Vue is very different but I have a Vue.js frontend project where I sent a picture file with FormData(): github.com/jlong4223/the-office-cl...
This is the best tutorial I have found for reactjs and nodemailer. Thank you for this.
I went through the comments and I saw that you did a followup for someone with react-hook-form. I also am using react-hook-form, and it helped me adapt to my code. However, I am attempting to use my form to send files through nodemailer. No matter where I look, I cannot find any information on getting the file data from react-hook-form into nodemailer. Would you happen to have any insight on this?
Hey not sure if you've already figured out the react portion of this question but with
react-hook-form
and files, all you'd have to do is add an input like this to your form:If you throw a
console.log
of the data in youronSubmit
, you should see the file info there. I'll follow up later on the nodemailer side!I have that part figured out already. I can get the data to my API, but what I can't figure out is how to make the 'file' attach with nodemailer. In my browser I see the file being sent like this:
"documentsUpload: FileList
0: File {name: 'Email Attachment test.txt', lastModified: 1647400270450, lastModifiedDate: Tue Mar 15 2022 22:11:10 GMT-0500 (Central Daylight Time), webkitRelativePath: '', size: 20, …}
length: 1"
But the data sent is blank:
"documentsUpload: { '0': {} }"
And nothing comes through on the email attachments.
Yeah I'm actually running into the same thing. I can see the file updating when I log it but when I send it, it goes through blank. Not super sure why that's happening yet. I'm going to try and see If throwing together a custom
onChange
for this file input helps. Not sure what's happening in the background ofreact-hook-form
with sending files.I actually got this figured out LATE last night. It was NOT a simple solution and was very picky.
That’s awesome! You mind sharing? Really curious to see what you came up with
This works with multi-file attachments too.
My handleChange()
So, in my API calling method I did:
and on the backend:
Nice! Solid work. Glad you figured it out and thanks for sharing
I edited it a dozen times to make sure I had it just right, for posterity. I really hope this helps someone later, because it was a pain to figure out, and searching yielded bits and pieces, but NOTHING on the backend portion.
Yeah it definitely will. I had a hard time finding quality full stack nodemailer stuff before putting this article together with bits and pieces that I found that worked. What really surprised me is how you were able to receive the file data on the api without needing a middleware package like multer. I’ll for sure be trying this.
I had to update. I took a part out I thought was no longer needed, and I was wrong. I guess there is your middleware you were talking about.
Thanks @chris and @jlong4223 for sharing this information.
Hey, really happy to hear that this helped you! This gets a little more complex and I'll definitely expand on this specific question with
react-hook-form
when I get a little more time.Until then, these resources may help:
You will most likely have to use FormData() to handling attaching a file on the frontend.
Didn't test these comments but this stackoverflow article about FormData & react looks promising on how to do it with a
handleChange
orhandleSubmit
function.On the backend, you will will have to at least use a library like
multer
to handle those file requests.I know Vue is very different but I have a
Vue.js
frontend project where I sent a picture file withFormData()
:github.com/jlong4223/the-office-cl...
This is another API of mine where I use
multer
to handle file requests. In this case, pictures:github.com/jlong4223/node-cloudina...
I will get back to this, but until this hopefully these help a little 😅