4

I am brand new to using node.js on the backend and still wrapping my head around building a REST API and making calls on my front end that hit my backend. With that said, I am trying to get my Angular 2 app to send an email using nodemailer. If I route to /sendEmail, the email sends perfectly however I am trying to get the call to run when I click submit on my form and then pass an object with all my form data in it so I can send with nodemailer. Any help here would be greatly appreciated! Thanks!

Ng2 Component HTML

<div class="centered two-thirds">
   <textarea name="project-description"></textarea>
   <input type="submit" (ngSubmit)="onSubmit()" name="submit" value="Submit" [disabled]=""class="tcenter centered">
</div>

Ng2 Component

onSubmit() {
    this._wpService.sendEmail();
  }

Ng2 Service

sendEmail() {
    return this._http.post('/api/sendEmail', {name: 'Foo', email: 'foo@foo.com'})
    .map((response: Response) => response.json() )
    .toPromise()
    .catch(this.handleError);
  }

Server.js

// Get Dependencies
const express = require('express');
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');
const nodemailer = require('nodemailer');

// Get our API routes
const api = require('./server/routes/api');

const app = express();

// Parsers for Post Data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// Point static path to dist
app.use(express.static(path.join(__dirname, 'dist')));

// Set our api routes
app.use('/api', api);

// Catch all other routes and return the index file
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist/index.html'));
});

// Get Port from environment and store in express
const port = process.env.PORT || '3000';
app.set('port', port);

const server = http.createServer(app);

server.listen(port, () => console.log(`API running on localhost:${port}`));

/server/routes/api.js

const express = require('express');
const router = express.Router();
const nodemailer = require('nodemailer');

/* GET api listing. */
router.get('/', (req, res) => {

  res.send('api works');

});


router.post('/sendEmail', (req, res) => {
  console.log(res);
  console.log(req);
  var smtpConfig = {
      host: 'smtp.gmail.com',
      port: 465,
      secure: true,
      auth: {
          user: 'my-email@gmail.com',
          pass: 'my-pass'
      }
  };

  var transporter = nodemailer.createTransport(smtpConfig);

  var mailOptions = {
      from: 'email',
      to: 'email',
      subject: 'Test',
      text: 'test'
  };

  transporter.sendMail(mailOptions, function(error, info){
      if(error){
          return console.log(error);
      }
      console.log('Message sent: ' + info.response);
  });
});

module.exports = router;

Console Error

POST http://localhost:3000/api/sendEmail 404 (Not Found) Response {_body: "Cannot POST /api/sendEmail↵", status: 404, ok: false, statusText: "Not Found", headers: Headers…} SyntaxError: Unexpected token C in JSON at position 0

  • What error(s) are you getting? As an aside, if you're trying to build a REST API, you should read up on RESTful services and standards. They're all noun-based, and centered around updating resources, not verb and action based (e.g. your /api/sendEmail endpoint). – Paul Jan 22 '17 at 21:19
  • Hi @Paul, thanks for the heads up I will definitely read more into that and adjust my code accordingly. I edited the original question with the console error. If I route to http://localhost:3000/api/sendEmail it sends perfectly, not sure why its not working when called. – Garrett Sanderson Jan 22 '17 at 21:33
  • Just realized the mistake.... I was doing a post call on the front end and my back end call was a get. I changed app.get to app.post and now its working as intended. Thanks for the help I will look at those REST API Docs. – Garrett Sanderson Jan 22 '17 at 21:57

0 Answers0