DEV Community

Discussion on: How to implement email functionality with Node.js, React.js, Nodemailer, and OAuth2

 
oicydwa profile image
Chris • Edited

This works with multi-file attachments too.

<Input
   type="file"
   ref={register}
   multiple
   {...register('file')}
   name={'file'}
   onChange={handleChange}
/>
Enter fullscreen mode Exit fullscreen mode

My handleChange()

const handleChange = async (e) => {
    setValue('file', e.target.value.files, {shouldDirty: true});
  }
Enter fullscreen mode Exit fullscreen mode

So, in my API calling method I did:

const fileUpload = require("express-fileupload"); // I don't know why
  app.use(express.urlencoded({ extended: true })); // But this is required. I dropped it
  app.use(fileUpload({
    createParentPath: true                        // and it stopped working.
  }));

 const sendEmail = async (data) => {
    let form = document.querySelector('form');
    const formData = new FormData(form);

    const {file} = data;

    for (let [index, value] of Object.entries(file)){
      formData.append(value.name, file[index]);
    }

    axios({
      method: 'post',
      url: 'http://localhost:3001/send',
      data: formData,
    });
  }
Enter fullscreen mode Exit fullscreen mode

and on the backend:

app.post('/send', async (req, res) => {

  const docs = Object.keys(req.files).map(key => {
    return {
      filename: req.files[key].name,
      content: req.files[key].data
    }
  });

  let mailOptions = {
    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',
      });
    }
  });
});
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
jlong4223 profile image
Jared Long

Nice! Solid work. Glad you figured it out and thanks for sharing

Thread Thread
 
oicydwa profile image
Chris

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.

Thread Thread
 
jlong4223 profile image
Jared Long

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.

Thread Thread
 
oicydwa profile image
Chris

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.

Thread Thread
 
vipcode786 profile image
VipCode786

Thanks @chris and @jlong4223 for sharing this information.