I am using a contact form in my application.In this i am sending the contact form details on a particular email id. All this i have to do in angular 6. I have tried this using nodemailer but not getting proper procedure to implement it. Thanks in advance
this is support.ts
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
import { client, response } from '../../interface'
import { ClientService } from '../../services/client.service'
import { EmailService } from '../../services/email.service'
import { Store } from '#ngrx/store'
import { AppState } from '../../app.state'
#Component({
selector: 'app-support',
templateUrl: './support.component.html',
styleUrls: ['./support.component.css']
})
export class SupportComponent implements OnInit {
angForm: FormGroup;
osVersion: {};
browserName: {};
browserVersion: {};
userAgent: {};
appVersion: {};
platform: {};
vendor: {};
osName : {};
clientList: client[]
clientListLoading: boolean = false;
orgMail: any;
user: any;
constructor(public clientService: ClientService,private store: Store<AppState>,
private fb: FormBuilder,
private emailService: EmailService) {
store.select('client').subscribe(clients => this.clientList = clients.filter(cli => cli.enabled == 0))
this.user = JSON.parse(localStorage.getItem('user'))
console.log(this.user);
{
this.createForm();
}
}
createForm() {
this.angForm = this.fb.group({
name: ['', Validators.required],
email: ['', Validators.required],
message: ['', Validators.required],
});
}
sendMail(name, email, message) {
this.emailService.sendEmail(name, email, message).subscribe(success => {
console.log(success);
}, error => {
console.log(error);
});
}
ngOnInit() {
// this.browser_details();
}
}
Html File:
<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>
<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>
contact.js
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;
server.js
// 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/components/support/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);
});
This my email.service.ts
import { Injectable } from '#angular/core';
import { Headers, Http, Response } from '#angular/http';
#Injectable({
providedIn: 'root'
})
export class EmailService {
constructor(private http: Http) { }
sendEmail(name, email, message) {
const uri = 'http://localhost:4200/support/contact';
const obj = {
name: name,
email: email,
message: message,
};
return this.http.post(uri, obj);
}
}
You should not use two ports on contact.js and the port 465 is the port secure so replace:
port: 465,
secure: false,
port: 25,
auth: {
user: 'email',
pass: 'pass'
},
tls: {
rejectUnauthorized: false
}
for:
port: 465,
secure: true,
auth: {
user: email,
pass: pass
}
On the variables email and pass you should set the email and password of account who go sent the email (I recommended create a new email account just for the form contact because gmail accounts by default not allows clients login without set up DMARK e DKIM) and always make sure to keep this informations out of public code repositories like GitHub.
You can see a similar code who I did on my github: https://github.com/anajuliabit/my-website-backend/blob/master/src/Controllers/ContactController.js
Related
So I am using a nodejs server to post contact form information from my react app into nodemailer so that I can send emails to my gmail account (this works fine and the emails come through) My question is I want to get React to respond to the response from the post request. (IE change state and then compile a message depending on that state). However when I send an email the page redirects to show just the plain json message sent from node. How can I stop this from happening? (Beginner here so please go easy!)
FORM FILE:
import React from 'react';`enter code here`
import './form.scss';
import axios from 'axios'
class Form extends React.Component{
constructor(){
super();
this.state= {
email: "",
topic: "",
query: "",
result: ""
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit = (event)=> {
const {email, topic, query, error, success} = this.state;
const data ={
email,
topic,
query
};
event.preventDefault();
axios
.post('http://localhost:5000/', data)
.then((res) => {
this.setState({result: "success"})
})
.catch(err => {
console.error(err)
this.setState({result: "fail"})
})
}
handleChange = (event) => this.setState({
[event.target.name]: event.target.value
});
render(){
const {result, topic, email, query} = this.state;
if(result === "success"){
return(<div>YES</div>);
}
if(result === "fail"){
return(<div>NO</div>);
}
else{
return(
<div>
<form action="/" method="POST" className="contact-form" >
<label className="contact-label">Email
<input type="text" name="email" value={email} onChange={this.handleChange} />
</label>
<label className="contact-label">Topic
<input type="text" name="topic" value={topic} onChange={this.handleChange}/>
</label>
<label className="contact-label">Query
<textarea name="query" value={query} onChange={this.handleChange} id="" cols="30" rows="10"></textarea>
</label>
<button type="submit" className="submit-button" onSubmit={this.handleSubmit}>Send Email</button>
</form>
</div>
)
}
}
}
export default Form;
NODEJS FILE:
const express = require('express')
const path = require('path');
const PORT = process.env.PORT || 5000;
const { body,validationResult } = require('express-validator');
const nodemailer = require("nodemailer");
const bodyParser = require('body-parser');
const app = express();
const cors = require('cors');
const { google } = require("googleapis");
const { reseller } = require('googleapis/build/src/apis/reseller');
const OAuth2 = google.auth.OAuth2;
require('dotenv').config()
app.use(express.static('public'));
app.use(bodyParser.json());
app.use(express.urlencoded({
extended: true
}))
if (process.env.NODE_ENV === 'production'){
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('*', function(req,res){
res.sendFile(path.join(__dirname, 'client/build' , 'index.html'))
})
}
app.use(
cors({
origin: 'http://localhost:3000',
credentials: true,
})
);
app.route('/')
.post([body('email').isEmail()],(req,res) => {
const errors = validationResult(req);
const email = req.body.email
const topic = req.body.topic
const query = req.body.query
const body = `${email} sent a message with the topic: ${topic} and content: ${query} `
const myOAuth2Client = new OAuth2(
process.env.CLIENT_ID,
process.env.CLIENT_SECRET,
"https://developers.google.com/oauthplayground"
)
myOAuth2Client.setCredentials({
refresh_token: process.env.REFRESH_TOKEN
});
const myAccessToken = myOAuth2Client.getAccessToken()
const transport = nodemailer.createTransport({
service: "gmail",
auth: {
type: "OAuth2",
user: process.env.SECRET_EMAIL, //your gmail account you used to set the project up in google cloud console"
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
refreshToken: process.env.REFRESH_TOKEN,
accessToken: myAccessToken //access token variable we defined earlier
}});
const mailOptions = {
from: email,
to: process.env.SECRET_EMAIL,
subject: topic,
text: body
};
if (!errors.isEmpty()) {
console.log(error)
} else {
transport.sendMail(mailOptions, function(error, info){
if(error){
res.status(400).send({message: "failed"})
}else{
res.status(200).send({message: "success"})
};
});
}
});
app.listen(PORT, () => {
console.log(`Listening on port ${PORT}!`)
});
I'm trying to create login/registration for an app using React/Node/Express/Postgres. Where I'm getting stuck is receiving data on the server side from my form in React.
I have a register component for the form in register.js
import React from 'react';
import useForm from '../form/useForm';
const Register = () => {
const { values, handleChange, handleSubmit } = useForm({
name: '',
email: '',
password: "",
password2: ""
}, register);
function register() {
console.log(values);
}
return (
<div className="row mt-5">
<div className="col-md-6 m-auto">
<div className="card card-body">
<h1 className="text-center mb-3">
<i className="fas fa-user-plus"></i> Register
</h1>
<form
action="/users/register"
method="POST"
onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="name">Name</label>
<input
className="form-control"
type="name"
name="name"
onChange={handleChange}
placeholder="Enter Name"
value={values.name}
required />
</div>
<div className="form-group">
<label htmlFor="email">Email</label>
<input
className="form-control"
type="email"
name="email"
onChange={handleChange}
placeholder="Enter Email"
value={values.email}
required />
</div>
<div className="form-group">
<label htmlFor="email">Password</label>
<input
className="form-control"
type="password"
name="password"
onChange={handleChange}
placeholder="Create Password"
value={values.password}
required />
</div>
<div className="form-group">
<label htmlFor="email">Confirm Password</label>
<input
className="form-control"
type="password"
name="password2"
onChange={handleChange}
placeholder="Confirm Password"
value={values.password2}
required />
</div>
<button type="submit" className="btn btn-primary btn-block">
Register
</button>
</form>
<p className="lead mt-4">Have An Account? Login</p>
</div>
</div>
</div>
);
};
export default Register;
A hook to handle the form actions in useForm.js
import {useState, useEffect} from 'react';
const useForm = (initialValues, callback) => {
const [hasError, setErrors] = useState(false);
const [values, setValues] = useState(initialValues);
const handleSubmit = (event) => {
if (event) event.preventDefault();
const options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(setValues(values => ({ ...values, [event.target.name]: event.target.value })))
}
fetch("/users/register", options)
}
const handleChange = (event) => {
event.persist();
setValues(values => ({ ...values, [event.target.name]: event.target.value }));
};
return {
handleChange,
handleSubmit,
values,
}
};
export default useForm;
Then I have a file to manage the routes for logging in/registering in users.js
const express = require("express");
const Router = require("express-promise-router");
const db = require("../db");
const router = new Router();
//Login page
router.get('/login', (req, res) => res.send("Login"));
//Register page
router.get('/register', (req, res) => res.send("Register"));
//Register Handle
router.post('/register', (req, res) => {
console.log(req.body);
res.send('hecks');
});
module.exports = router;
I have tried messing with things inside of the handleSubmit function in my useForm.js hook, but everything leads to the console.log(req.body) from my users.js file to return as undefined. Where am I going wrong?
Edit #1: Snip from Postman sending post request
Edit #2: basic project structure
.
./client
./client/src
./client/src/components
./client/src/components/register
./client/src/components/register/register.js
./client/src/components/form
./client/src/components/form/useForm.js
./client/src/App.js
./routes
./routes/index.js
./routes/users.js
./server.js
Edit #3: Main server.js file
const express = require("express");
const mountRoutes = require("./routes");
const app = express();
mountRoutes(app);
var bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//catch all other routes
app.get("*", function(req, res) {
res.send("<h1>Page does not exist, sorry</h1>");
});
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
Youβre setting state in JSON.stringify which returns undefined. youβve to pass values in it:
const handleSubmit = (event) => {
if (event) event.preventDefault();
const options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(values)
}
fetch("/users/register", options)
}
You need to apply bodyParser before mounting routes.
So change like this:
var bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
mountRoutes(app);
You don't use then or await in the handleSubmit function which may cause problem.
Can you update the handleSubmit function like this and try?
const handleSubmit = async event => {
if (event) event.preventDefault();
const options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(values)
};
try {
const response = await fetch("/users/register", options);
const responseData = await response.json();
if (response.ok) {
console.log("response ok");
callback();
} else {
console.log("response NOT ok");
throw new Error(responseData.message);
}
} catch (err) {
console.log(err);
if (err.response) {
console.log(err.response.data);
}
}
};
π¨βπ« You can try with this code below:
userForm.js: Make sure your handleSubmit in your userForm.js it's looks like this code below: π
const handleSubmit = async(event) => {
if (event) event.preventDefault();
const options = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(values)
}
try {
// change with your endpoint
const endpoint = 'http://localhost:3001/users/register';
const result = await fetch(endpoint, options);
// send value to your register function
callback(result);
} catch (ex) {
console.log('Something failed');
console.log(ex);
}
}
You've to use callback(result), so you can console.log that value on your register function.
express server: Make sure in your express server, you've been add body-parser, it's will looks like this code below: π
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
That code above will make your req.body works.
I hope it can help you π.
I am trying to retrieve my jwt token after login within my Profile component and store the token as within localstorage. I know that localstorage isnt the best option but this will be a native mobile app so localstorage from what I know is my best option. However when I sign in , I receive a token , here is an token that Ive received recently
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjaGVjayI6dHJ1ZSwiaWF0IjoxNTYzMDUzMzk4LCJleHAiOjE1NjMwNTQ4Mzh9.tw8ks-jFZID5rmwhoNTkWV8598niE3zMFIDk4Gz-sVg
when my Profile component trys to retrieve /current it use jwt malformed
Server.js
var express = require('express');
var cors = require('cors');
var bodyParser = require('body-parser');
var app = express();
var port = process.env.PORT || 5000;
var morgan = require('morgan');
const auth = require('./middleware/auth');
const User = require('./models/User');
app.use(cors());
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
/*========= Here we want to let the server know that we should expect and allow a header with the content-type of 'Authorization' ============*/
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Headers', 'Content-type,Authorization');
next();
});
// use morgan to log requests to the console
app.use(morgan('dev'));
var Users = require('./routes/Users');
app.use('/users', Users);
// Create a Server
const PORT = process.env.PORT || 5000; // Environment variable or port 5000
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
module.exports = app;
User.js
const express = require('express');
const users = express.Router();
const cors = require('cors');
const jwt = require('jsonwebtoken');
var exjwt = require('express-jwt');
var jwtauth = require('../middleware/authjwt.js');
const bcrypt = require('bcrypt');
const bodyParser = require('body-parser');
const User = require('../models/User');
const config = require('config');
const auth = require('../middleware/auth');
const secret = 'dasdsad';
users.use(
bodyParser.urlencoded({
extended: true
})
);
users.use(bodyParser.json());
users.use(cors());
users.post('/register', (req, res) => {
const today = new Date();
const userData = {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: req.body.password,
created: today
};
User.findOne({
where: {
email: req.body.email
}
})
//TODO bcrypt
//Need validation to appear on console and in view
.then(user => {
if (!user) {
bcrypt.hash(req.body.password, 10, (err, hash) => {
userData.password = hash;
User.create(userData)
.then(user => {
res.json({ status: user.email + 'Registered!' });
})
.catch(err => {
res.send('error: ' + err);
});
});
} else {
res.json({ error: 'User already exists' });
}
})
.catch(err => {
res.send('error: ' + err);
});
});
users.post('/authenticate', (req, res) => {
User.findOne({
where: {
email: req.body.email
}
}).then(user => {
if (user) {
if (bcrypt.compareSync(req.body.password, user.password)) {
const payload = {
check: true
};
const token = jwt.sign(payload, config.get('myprivatekey'), {
expiresIn: 1440 // expires in 24 hours
});
res.json({
message: 'authentication done ',
token: token
});
console.log('Successful Login');
console.log(user.first_name);
} else {
res.json({ message: 'please check your password !' });
console.log('incorrect password');
}
} else {
res.json({ message: 'user not found !' });
console.log('user cannot be found');
}
});
});
//users.get('/something', [express.bodyParser(), jwtauth], function(req, res) {
// do something
//});
// app.all('/api/*', [express.bodyParser(), jwtauth]);
users.get(
'/current',
exjwt({ secret: config.get('myprivatekey') }),
async (req, res) => {
const user = await User.findById(req.user._id).select('-password');
console.log(user);
res.send(user);
}
);
Login
import React, { Component } from 'react';
class Login extends Component {
constructor() {
super();
this.state = {
email: '',
password: '',
errors: {}
};
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
onSubmit(e) {
e.preventDefault();
const user = {
email: this.state.email,
password: this.state.password
};
var token = window.localStorage.getItem('token');
fetch('http://localhost:5000/users/authenticate', {
method: 'POST', // or 'PUT'
body: JSON.stringify(user), // data can be `string` or {object}!
headers: {
'Content-Type': 'application/json'
}
});
}
render() {
return (
<div className='container'>
<div className='row'>
<div className='col-md-6 mt-5 mx-auto'>
<form noValidate onSubmit={this.onSubmit}>
<h1 className='h3 mb-3 font-weight-normal'>Please sign in</h1>
<div className='form-group'>
<label htmlFor='email'>Email address</label>
<input
type='email'
className='form-control'
name='email'
placeholder='Enter email'
value={this.state.email}
onChange={this.onChange}
/>
</div>
<div className='form-group'>
<label htmlFor='password'>Password</label>
<input
type='password'
className='form-control'
name='password'
placeholder='Password'
value={this.state.password}
onChange={this.onChange}
/>
</div>
<button
type='submit'
className='btn btn-lg btn-primary btn-block'
>
Sign in
</button>
</form>
</div>
</div>
</div>
);
}
}
export default Login;
This is how I am currently fetching the token within My Profile component
componentDidMount() {
var token = localStorage.getItem('token');
fetch('http://localhost:5000/users/current', {
//cahng taht
method: 'GET',
mode: 'cors',
headers: { Authorization: 'Bearer ' + token }
});
}
I guess the problem is on the expiresIn. 'expiresIn' expressed in seconds or a string describing a time span. You set 1440, which means 1440/60 = 24minutes => expires after 24 minutes not after 24 hours... Could you please try to set as below:
const token = jwt.sign(payload, config.get('myprivatekey'), {
expiresIn: '24h' // expires in 24 hours
});
I have a bootstrap form for email services for angular 6 app and nodejs, I am using nodemailer for sendemail in my app, unfortunatelly does not work. I am getting the following error when I submit the form:
zone.js:2969 POST http://localhost:4200/contact/send 404 (Not Found)
here is the form HTML
<form [formGroup]="angForm" novalidate method="POST">
<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 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() {
}
}
Here is service.ts
import { Injectable } from '#angular/core';
import { Headers, Http, Response } from '#angular/http';
import { Jsonp } from '#angular/http';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '#angular/common/http';
import { Observable } from '../../node_modules/rxjs';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
const apiUrl = 'http://localhost:4200/contact';
#Injectable({
providedIn: 'root'
})
export class ContactService {
sendEmailUrl = '/send';
constructor(private http: Http) { }
sendEmail(name, email, message): Observable<any> {
const uri = `${apiUrl + this.sendEmailUrl}`;
const obj = {
name: name,
email: email,
message: message,
};
return this.http.post(uri, obj);
}
}
Here is the server .js
// 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);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// For all GET requests, send back index.html
// so that PathLocationStrategy can be used
app.get('/*', function (req, res, next) {
res.sendFile(path.join(__dirname + '/majeni/dist/majeni/index.html'));
});
// Start Server
app.listen(port, () => {
console.log('Server started on port ' + port);
});
Here is contact.js (routes settings)
const express = require('express');
const router = express.Router();
const request = require('request');
const nodemailer = require('nodemailer');
router.post('/send', (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: 'Myemail',
pass: 'my pass'
},
tls: {
rejectUnauthorized: false
}
});
let HelperOptions = {
from: '"Jini" <myEmail',
to: 'myEmail',
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;
what is missing in my code?
The port of your server is 3000
const port = process.env.PORT || 3000
so you have to change this:
const apiUrl = 'http://localhost:4200/contact';
to
const apiUrl = 'http://localhost:3000/contact';
I have a bootstrap form for email services for angular 6 app and nodejs, I am using nodemailer for sendemail in my app, unfortunatelly does not work. I ma getting the following error:
Failed to load resource: net::ERR_CONNECTION_REFUSED : :3000/contact/send:1
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');
router.get('/send', (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({
service: 'gmail',
secure: false,
port: 25,
auth: {
user: 'MY EMAIL',
pass: 'THE PASSWORD'
},
tls: {
rejectUnauthorized: false
}
});
let HelperOptions = {
from: '"MYNAME" <MYEMAIL,
to: 'MYEMAIL',
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.
// server.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require('path');
const app = express();
// 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.json());
//routes
const contact = require('./app/routes/contact');
app.use('/contact', contact);
// CORS Middleware
app.use(cors());
// 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());
// 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);
}
}
What is missing in my code?
Failed to load resource: net::ERR_CONNECTION_REFUSED : :3000/contact/send:1
Your error means your client application is Unable to connect to your nodejs server.
Fix
Your code :
const uri = 'http://localhost:3000/contact/send';
Will work if nodejs server is running on port 3000 on localhost.
For anyone else getting this error.
Check that your NodeJS is not crashing. If a previous request causes your NodeJS server to crash or restart this is the same error on subsequent requests.
make sure your spring boot project is also running with angular project.