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.
Related
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 create an Angular app that sends an email using Nodemailer.
I am able to create a standard Angular app that contains a form. I then want to pass data from this form to a .JS file which will then use Nodemailer to send that data to an email address.
All the examples I have found so far for Nodemailer use View engines such as handlebars, etc. but I want to use my angular app's HTML rather than a view engine.
How do I pass data from my Angular app's form to a .JS file to send an email without having to use a View Engine?
Below is what I have so far in my Angular app:
<form method="POST" action="send">
<p>
<label>Name</label>
<input type="text" name="name">
</p>
<p>
<label>Company</label>
<input type="text" name="company">
</p>
<p>
<label>Email Address</label>
<input type="email" name="email">
</p>
<p>
<label>Phone Number</label>
<input type="text" name="phone">
</p>
<p class="full">
<label>Message</label>
<textarea name="message" rows="5"></textarea>
</p>
<p class="full">
<button type="submit">Submit</button>
</p>
</form>
And this is what I have in the tutorial code:
APP.JS
const express = require("express");
const bodyParser = require("body-parser");
const exphbs = require("express-handlebars");
const path = require("path");
const nodemailer = require("nodemailer");
const app = express();
// View engine setup
app.engine("handlebars", exphbs());
app.set("view engine", "handlebars");
// Static folder
app.use("/public", express.static(path.join(__dirname, "public")));
// Body Parser Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get("/", (req, res) => {
res.render("contact");
});
app.post("/send", async (req, res) => {
const output = `
<p>You have a new contact request</p>
<h3>Contact Details</h3>
<ul>
<li>Name: ${req.body.name}</li>
<li>Company: ${req.body.company}</li>
<li>Email: ${req.body.email}</li>
<li>Phone: ${req.body.phone}</li>
</ul>
<h3>Message</h3>
<p>${req.body.message}</p>
`;
try{
var transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "myemail#mail.com",
pass: "myPassword"
},
tls: {
rejectUnauthorized: false
}
});
}
catch(err){
console.log(err.message);
}
const mailOptions = {
from: "myemail#mail.com", // sender address
to: "myemail#mail.com", // list of receivers
subject: "Test email", // Subject line
html: output // plain text body
};
let info = await transporter.sendMail(mailOptions);
console.log("Message sent: %s", info.messageId);
console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
res.render("contact", { msg: "Email has been sent" });
});
app.listen(3000, () => console.log("Server started..."));
CONTACT.HANDLEBARS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Acme Web Design</title>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.css" />
<link rel="stylesheet" href="public/css/style.css">
</head>
<body>
<div class="container">
<h1 class="brand"><span>Acme</span> Web Design</h1>
<div class="wrapper animated bounceInLeft">
<div class="company-info">
<h3>Acme Web Design</h3>
<ul>
<li><i class="fa fa-road"></i> 44 Something st</li>
<li><i class="fa fa-phone"></i> (555) 555-5555</li>
<li><i class="fa fa-envelope"></i> test#acme.test</li>
</ul>
</div>
<div class="contact">
<h3>Email Us</h3>
{{ msg }}
<form method="POST" action="send">
<p>
<label>Name</label>
<input type="text" name="name">
</p>
<p>
<label>Company</label>
<input type="text" name="company">
</p>
<p>
<label>Email Address</label>
<input type="email" name="email">
</p>
<p>
<label>Phone Number</label>
<input type="text" name="phone">
</p>
<p class="full">
<label>Message</label>
<textarea name="message" rows="5"></textarea>
</p>
<p class="full">
<button type="submit">Submit</button>
</p>
</form>
</div>
</div>
</div>
</body>
I can post further code if necessary.
So I managed to pass data from the form (root.component.html) to the server (app.js), capture it & print it to the console via the POST method.
Code is below:
root.component.html:
<form #emailForm="ngForm">
<div class="col-md-6">
<div>
<label for="username">
Username
</label>
<input
type="text"
id="username"
[(ngModel)]="username"
required
name="username"
#txtUsername="ngModel"
/>
</div>
<div>
<label for="message">Message</label>
<textarea
id="message"
placeholder="Please enter your message here"
[(ngModel)]="message"
required
name="message"
#txtMessage="ngModel"
></textarea>
</div>
<button
axis-button
class="axis-btn"
title="Submit"
data-kind="primary"
(click)="sendMessage()"
[disabled]="emailForm.invalid"
>
Send Email
</button>
</div>
</form>
root.component.ts:
export class RootComponent implements OnInit {
constructor(private rootService: RootService) {}
username: string;
message: string;
ngOnInit() {
this.getData();
}
getData() {
this.rootService.getAPIData().subscribe(
response => {
console.log('response from GET API is ', response);
},
error => {
console.log('error is ', error);
}
);
}
postData(name: string, message: string) {
this.rootService.postAPIData(name, message).subscribe(
response => {
console.log('response from POST API is ', response);
},
error => {
console.log('error during post is ', error);
}
);
}
sendMessage() {
this.postData(this.username, this.message);
}
}
root.service.ts:
export class RootService {
constructor(private http: HttpClient) {}
getAPIData() {
return this.http.get('https://jsonplaceholder.typicode.com/users');
}
postAPIData(name: string, message: string) {
return this.http.post('/api/postData', {
name: name,
message: message
});
}
}
app.js:
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
app.get('/', (req, res) => {
res.send('Welcome to Node API')
})
app.get('/getData', (req, res) => {
res.json({'message': 'Hello World'})
})
app.post('/postData', bodyParser.json(), (req, res) => {
res.json(req.body) // Prints the request body to the browser console
const output = `Name: ${req.body.name}......Email: ${req.body.message}`;
console.log(output);
})
app.listen(3000, () => console.log('Example app listening on port 3000!'))
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
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'd like to know if it's possible to rewrite an url with express.
I actually have this code :
var http, express, app;
http = require("http");
express = require("express");
app = express();
app.use(express.json())
app.use(express.urlencoded())
.post("/ajax_login", function (req, res) {
"use strict";
http.get({ host: "localhost", port: 8080, path: "/users/" + req.body.email + "/email" }, function (resp) {
resp.setEncoding("utf8");
resp.on("data", function (data) {
json = JSON.parse(data);
if (json.password.password === sha1(req.body.password))ย {
res.render("home.ejs");
} else {
res.render("login.ejs", { email : req.body.email, error : "password is not good" });
}
});
});
})
.get("/login", function (req, res) {
"use strict";
res.render("login.ejs");
})
.listen(3030);
I call /ajax_login from a form :
<form method="post" action="/ajax_login">
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" id="email" name="email" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password" name="password" />
</div>
<button type="submit" class="btn btn-primary">Connection</button>
</form>
The problem is : when I call /ajax_login, after res.render my HTML code on my browser is changed, but the url still /ajax_login.
How I can change this URL ?
I know the javascript solution :
window.history.pushState("", document.title, "/login");
But, I'd like to know if a solution exist from the server.
Thanks
I would add an error to the request locals, redirect to login, and then check if an error exists when rendering the login page.
.post("/ajax_login", function (req, res) {
"use strict";
...
if (password && email IS OK) {
res.locals.errorMSG = "password is not good";
res.redirect("/login"); //redirect vs render
} else {
res.render("home.ejs");
}
})
.get("/login", function (req, res) {
"use strict";
res.render("login.ejs", {error: res.locals.errorMSG || null});
})
res.locals
res.redirect