Send email using nodemailer angular 6

16,757

Your forceSSL function is redirecting your http call to an non existing https endpoint.

All the code looks fine btw 😊

Comment out this line in server.js

// app.use(forceSSL());

Edit

Also change the endpoint in your service to match what you have in the server, it should be /contact only 😊

app.use('/contact', contact);
Share:
16,757
The Dead Man
Author by

The Dead Man

Updated on June 04, 2022

Comments

  • The Dead Man
    The Dead Man almost 2 years

    I have a bootstrap form for email services for angular 6 app and nodejs, I am using nodemailer for sendemail in my app, unfortunately does not work. I am getting the following error when I submit the form:

    OPTIONS https://localhost:3000/contact/send 0 ()

    here is the form

     <form [formGroup]="angForm" novalidate>
        <div class="message">
          <h3> Write to us </h3>
        </div>
        <div class="form__top">
          <div class="form__left">
            <div class="form__group">
              <input class="form__input form__input--name" type="text"   formControlName="name" placeholder="name" #name>
            </div>
            <div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)" class="alert alert-danger">
              <div *ngIf="angForm.controls['name'].errors.required">
                Name is required.
              </div>
            </div>
            <div class="form__group">
              <input class="form__input form__input--email" type="email"  formControlName="email" placeholder="email" #email>
            </div>
            <div *ngIf="angForm.controls['email'].invalid && (angForm.controls['message'].dirty || angForm.controls['message'].touched)"
              class="alert alert-danger">
              <div *ngIf="angForm.controls['message'].errors.required">
                message is required.
              </div>
            </div>
          </div>
          <div class="form__right">
            <div class="form__group">
              <textarea class="form__input form__input--textarea" placeholder="Message" formControlName="message"  #message
                rows="3"></textarea>
            </div>
            <div *ngIf="angForm.controls['message'].invalid && (angForm.controls['message'].dirty || angForm.controls['message'].touched)"
              class="alert alert-danger">
              <div *ngIf="angForm.controls['message'].errors.required">
                message is required.
              </div>
            </div>
          </div>
        </div>
        <flash-messages></flash-messages>
        <div class="form__down">
          <div class="form__group">
            <button (click)="sendMail(name.value, email.value, message.value)" [disabled]="angForm.pristine || angForm.invalid"  class="form__input form__input--submit" name="submit" type="submit" value="SEND MESSAGE">SEND MESSAGE
            </button>
          </div>
        </div>
    
      </form>
    

    Here is contact,js (node mailer settings and routes)

      const express = require('express');
    const router = express.Router();
    const request = require('request');
    const nodemailer = require('nodemailer');
    const cors = require('cors');
    
    router.options('/send', cors()); 
    router.get('/send', cors(), (req, res) => {
        const outputData = `
        <p>You have a new contact request</p>
        <h3>Contact Details</h3>
        <ul>  
          <li>Name: ${req.body.name}</li>
          <li>Email: ${req.body.email}</li>
        </ul>
        <h3>Message</h3>
        <p>${req.body.message}</p>
      `;
    
        let transporter = nodemailer.createTransport({
            host: 'smtp.gmail.com',
            port: 465,
            secure: false,
            port: 25,
            auth: {
                user: 'email',
                pass: 'pass'
            },
            tls: {
                rejectUnauthorized: false
            }
        });
    
        let HelperOptions = {
            from: '"kutomba" <email',
            to: 'email',
            subject: 'Majeni Contact Request',
            text: 'Hello',
            html: outputData
        };
    
    
    
        transporter.sendMail(HelperOptions, (error, info) => {
            if (error) {
                return console.log(error);
            }
            console.log("The message was sent!");
            console.log(info);
        });
    
    });
    module.exports = router;
    

    here is the server js. UPDATE

    // server.js
    const express = require('express');
    const bodyParser = require('body-parser');
    const cors = require('cors');
    const path = require('path');
    const app = express();
    // CORS Middleware
    app.use(cors());
    // Port Number
    const port = process.env.PORT || 3000
    // Run the app by serving the static files
    // in the dist directory
    app.use(express.static(path.join(__dirname, '/majeni/dist/majeni')));
    // Body Parser Middleware
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(bodyParser.json());
    //routes
    const contact = require('./app/routes/contact');
    app.use('/contact', contact);
    // If an incoming request uses
    // a protocol other than HTTPS,
    // redirect that request to the
    // same url but with HTTPS
    const forceSSL = function () {
      return function (req, res, next) {
        if (req.headers['x-forwarded-proto'] !== 'https') {
          return res.redirect(
            ['https://', req.get('Host'), req.url].join('')
          );
        }
        next();
      }
    }
    
    // Instruct the app
    // to use the forceSSL
    // middleware
    app.use(forceSSL());
    app.use(function (req, res, next) {
    
      // Website you wish to allow to connect
      res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
    
      // Request methods you wish to allow
      res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    
      // Request headers you wish to allow
      res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    
      // Set to true if you need the website to include cookies in the requests sent
      // to the API (e.g. in case you use sessions)
      res.setHeader('Access-Control-Allow-Credentials', true);
    
      // Pass to next layer of middleware
      if ('OPTIONS' == req.method) {
        res.sendStatus(200);
        } else {
          next();
        }
    
    });
    
    // For all GET requests, send back index.html
    // so that PathLocationStrategy can be used
    app.get('/*', function (req, res) {
      res.sendFile(path.join(__dirname + '/majeni/dist/majeni/index.html'));
    });
    
    // Start Server
    app.listen(port, () => {
        console.log('Server started on port '+port);
      });
    

    UPDATE

    Here is service

    import { Injectable } from '@angular/core';
    import { Headers, Http, Response } from '@angular/http';
    import { Jsonp } from '@angular/http';
    @Injectable({
      providedIn: 'root'
    })
    export class ContactService {
    
      constructor(private http: Http) { }
    
      sendEmail(name, email, message) {
        const uri = 'http://localhost:3000/contact/send';
        const obj = {
          name: name,
          email: email,
          message: message,
        };
        return this.http.post(uri, obj);
      }
    }
    

    UPDATE : component.ts

    import { Component, OnInit } from '@angular/core';
    import { ContactService } from '../../contact.service';
    import { FormGroup, FormBuilder, Validators } from '@angular/forms';
    import { FlashMessagesModule, FlashMessagesService } from 'angular2-flash-messages';
    @Component({
      selector: 'app-footer',
      templateUrl: './footer.component.html',
      styleUrls: ['./footer.component.scss']
    })
    export class FooterComponent implements OnInit {
      angForm: FormGroup;
      constructor(
        private flashMessages: FlashMessagesService,
        private fb: FormBuilder,
        private contactService: ContactService) {
        this.createForm();
      }
    
      createForm() {
        this.angForm = this.fb.group({
          name: ['', Validators.required],
          email: ['', Validators.required],
          message: ['', Validators.required],
        });
      }
      sendMail(name, email, message) {
        this.contactService.sendEmail(name, email, message).subscribe(success => {
          this.flashMessages.show('You are data we succesfully submitted', { cssClass: 'alert-success', timeout: 3000 });
          console.log(success);
        }, error => {
          this.flashMessages.show('Something went wrong', { cssClass: 'alert-danger', timeout: 3000 });
        });
      }
      ngOnInit() {
      }
    
    }
    

    What is missing in my code?

  • hamilton.lima
    hamilton.lima over 5 years
    Updated the response ;) have fun