Here is a link to the repo: https://github.com/mcs415/nodemailer-heroku
The repo is basically a replica of Brad Travery's tutorial: https://www.youtube.com/watch?v=nF9g1825mwk
The node server works on localhost, but when I submit I get a POST error and I get no information after that.
I started searching for Nodemailer POST error on the web then I came to the conclusion it was probably express.
I'm using Gmail. It was initially suggested to use Zoho mail at first. Im using Apps less secure option, the code on the repo has no password filled in. I thought I would deal with the POST error first.
I set up Heroku and then tried to create the app via the CLI, it looked good then I got an err for: no start script, I searched that and found to include a line after the test in the JSON file, then my server neglected to run at all. So one thing at a time. First POST error, then Heroku, then GMAIL, possibly 0auth option or another email account.
<!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>Contact Morgan</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">
<ul>
<li><i class="fa fa-road"></i></li>
<li><i class="fa fa-phone"></i></li>
<li><i class="fa fa-envelope"></i> msippel415#gmail.com</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>
<p>Thank you Brad at Traversy media for the tutorial!</p>
</div>
</div>
</div>
</body>
</html>
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', {layout: false});
});
app.post('/send', (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>
`;
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: 'msippel415#gmail.com', // generated ethereal user
pass: '********' // generated ethereal password
},
tls:{
rejectUnauthorized:false
}
});
// setup email data with unicode symbols
let mailOptions = {
from: '"Nodemailer Contact" <msippel415#gmail.com>', // sender address
to: 'msippel415#gmail.com', // list of receivers
subject: 'Node Contact Request', // Subject line
text: 'Hello world?', // plain text body
html: output // html body
};
// send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
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...'));
json
{
"name": "nodecontactform",
"version": "1.0.0",
"description": "sample app using nodemailer",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "mcs",
"license": "MIT",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"express-handlebars": "^3.1.0",
"i": "^0.3.6",
"nodemailer": "^6.4.2",
"npm": "^6.13.4"
}
}
Your first error Cannot POST / can be fixed by adding an = sign to your <form> tags action attribute:
<form method="POST" action="/send">
In your version, you were actually making this request POST / when you wanted POST /send.
The other errors are best handled by just copying the code that Nodemailer provides. I pulled in your project and edited app.js to conform to Nodemailer's example and it worked fine. You need to adjust the call to res.render in the POST /send route to add the layout:false option:
res.render('contact', { layout: false, msg:'Email has been sent'});
And you need to generate an ethereal user and use those credentials:
// Only needed if you don't have a real mail account for testing
let testAccount = await nodemailer.createTestAccount();
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: "smtp.ethereal.email",
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: testAccount.user, // generated ethereal user
pass: testAccount.pass // generated ethereal password
}
});
Here is the full code from app.js that I used to get it working:
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', {layout: false});
});
app.post('/send', (req, res) => {
const mailBody = `
<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>
`;
sendMail(mailBody).catch(console.error);
res.render('contact', { layout: false, msg:'Email has been sent'});
});
// async..await is not allowed in global scope, must use a wrapper
async function sendMail(html) {
// Generate test SMTP service account from ethereal.email
// Only needed if you don't have a real mail account for testing
let testAccount = await nodemailer.createTestAccount();
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: "smtp.ethereal.email",
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: testAccount.user, // generated ethereal user
pass: testAccount.pass // generated ethereal password
}
});
// send mail with defined transport object
let info = await transporter.sendMail({
from: '"Fred Foo 👻" <foo#example.com>', // sender address
to: "bar#example.com, baz#example.com", // list of receivers
subject: "Hello ✔", // Subject line
text: "Hello world?", // plain text body
html // html body
});
console.log("Message sent: %s", info.messageId);
// Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321#example.com>
// Preview only available when sending through an Ethereal account
console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
// Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
}
app.listen(3000, () => console.log('Server started...'));
And here is a gif to show how it looks:
You can find a fork of the project that works as expected here: nodemailer-repo
https://nodemailer-mcs.herokuapp.com/
It took some work to get it on Heroku but I'm happy, with the end result, I wouldnt of done it without dan's help, the ethereal email, gave me a lot of hope. There were some settings with heroku, with a Profile, start script settings and listen on port: process.env.PORT || 3000;
Related
I am trying to build simple login page using node.js with express.js package and mysql package, that will redirect the user to layout.html page, if the username and password exists in mysql database.
I run mysql on my localhost, and I've created a database with tables and users in mysql workbench.
The node.js server is also being run on localhost using liteserver.
After I am clicking on "Submit" button on my page, no matter if there is any data written into (username) and (password) boxes, I am getting an Error saying "Cannot POST /login"
That is all the code I have, all my javascript code is in one file.
**script.js
**
import express from 'express';
const app = express();
import { createConnection } from 'mysql';
import bodyParser from 'body-parser';
const router = express.Router();
// Create a connection to the MySQL server
const connection = createConnection({
host: 'localhost', // The hostname of the MySQL server
user: 'pablo', // The username to connect to the server
password: 'KotWButach!', // The password for the usernam
database: 'logowanie' // The name of the database
});
// Connect to the MySQL server
connection.connect();
connection.connect((err) => {
if (err) {
console.error(`Error connecting to the database: ${err.stack}`);
return;
}
console.log(`Connected to the database with id: ${connection.threadId}`);
});
connection.query(query, (error, results) => {
if (error) {
console.error(`Error executing the query: ${error.stack}`);
return res.status(500).send({ error });
}
});
// Parse the request body
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
router.post('/login');
app.post('/login', (req, res) => {
const { username, password } = req.body; // Destructure the username and password from the request body
// Query the users table to check if the provided username and password match a record in the table
const query = `SELECT * FROM users WHERE UserName = '${username}' AND UserPass = '${password}'`;
connection.query(query, (error, results) => {
if (error) {
return res.status(500).send({ error });
}
if (results.length === 0) {
return res.status(401).send({ message: 'Invalid username or password' });
}
// If the username and password match a record in the table, redirect to the layout.html page
res.redirect('/layout.html');
});
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
index.html
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'nonce-randomvalue'">
<head>
<link rel="stylesheet" type="text/css" href="styles.css">
<title>Login</title>
<script nonce="randomvalue" src="script.js"></script>
</head>
<body>
<form action="/login" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<br>
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
I am expecting it to be able to redirect to layout.html after clicking submit (with credentials that match with the ones in the database), or get an error saying "invalid username or password" it they aren't matching.
I've scrolled through more than 30 cases on stackoverflow and none of the answers seem to work or me, I've even asked ai for what to do but it got stuck on the loop telling me to check if my routing is correct.
You could simply remove theses lines in your code that cause the error that you have :
Remove just this line :
router.post('/login');
You declare a api endpoint which has no callback behind and point to "/login", that's why you have the error.
After remove it, you can also remove the router you declare previously as you won't need it anymore.
I'm trying to get form inputs data on the console of node.js, but, it's showing an empty Curly brace.
I used postman to check whether the data is received or not, it's working well, data has been received successfully on the terminal console.
<-------- I have taken the below steps to get the data from POSTMAN -------->
step-1: created a new collection and selected a post request
step-2: entered request URL
(http://localhost/loginandsingup)
step-3: in the header section, selected Content-Type in the key column and the value is application/json
step-4: added some data in the body section
{
"username": "shyam",
"email": "kumbamshyam955#gmai.com",
"mobilenumber": 6547896587,
"password": "superman145",
"confirmpassword": "superman145",
"checkbox": true
}
step-5: finally I clicked on the send button
Output from the postman, on terminal
[nodemon] restarting due to changes...
[nodemon] starting `node app.js`
Debugger listening on ws://127.0.0.1:61047/e3190b4a-b5a4-4806-9d45-c1f09c74212a
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
application had started successfully on port 80
database conencted successfuly
{
username: 'shyam',
email: 'kumbamshyam955#gmai.com',
mobilenumber: 6547896587,
password: 'superman145',
confirmpassword: 'superman145',
checkbox: true
}
<-------- Code to get the form inputs data from locally hosted website -------->
// I used node.js for the backend //
app.js (Backend code)
const app = express();
const dotenv = require("dotenv");
const path = require('path');
dotenv.config({path: './config.env'})
const User = require('./model/userschema.js')
require('./db/database-connection.js')
const port = process.env.PORT
app.use(express.json());
app.use(require('./router/auth'))
const staticpath = path.join(__dirname, '/public');
app.use(express.static(staticpath));
app.set('view engine', 'pug');
app.set('views', path.join(__dirname, '/view'));
const middleware = (req, res, next)=>{
console.log("hello i'm middleware")
next();
}
app.get('/', (req, res) => {
res.status(200).render('home.pug');
})
app.get('/loginandsingup', (req, res) => {
res.status(200).render('loginandsingup.pug');
})
app.get('/customerservice', (req, res) => {
res.status(200).render('customerservice.pug');
})
app.get('/product', (req, res) => {
res.status(200).render('product.pug');
})
app.get('/404', (req, res) => {
res.status(200).render('404.pug')
})
app.use((req, res) => {
res.redirect('/404')
})
app.listen(port, () => {
console.log(`application had started successfully on port ${port}`)
})
router/auth.js (Backend code)
const express = require('express');
const router = express.Router();
require('../db/database-connection');
const User = require('../model/userschema');
router.post('/loginandsingup',(req, res) => {
const body = req.body
console.log(body);
res.json({message: req.body});
})
module.exports = router;
loginandsingup.pug (pug code)
doctype html
html(lang="en")
head
meta(charset="UTF-8")
//- meta(http-equiv='refresh' content='30')
meta(http-equiv="X-UA-Compatible", content="IE=edge")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title Mens Fashion | Login & singup
style
include ../public/css/login-and-singup-folder/loginstyle.css
include ../public/css/main-css/style.css
link(href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css", rel="stylesheet",integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3", crossorigin="anonymous")
link(rel="preconnect", href="https://fonts.googleapis.com")
link(rel="preconnect", href="https://fonts.gstatic.com", crossorigin="")
link(href="https://fonts.googleapis.com/css2?family=Roboto&display=swap",rel="stylesheet")
body(style="background: rgba(236, 236, 236, 1)")
.loding-img-container
img#loading(src="images/Rolling scg.svg", alt="")
include navbar.pug
#login-and-singup-section.container
#login-and-singup-main-container.container.bg-light
#login-and-singup-container-1.login-and-singup-container.my-5
form#login-form
.mb-3
label.form-label(for='exampleInputEmail1') Email address
input#login-email.form-control(type='email' aria-describedby='emailHelp' autocomplete="off" placeholder="Enter Email")
.mb-3
label.form-label(for='exampleInputPassword1') Password
input#login-password.form-control(type='password' autocomplete="off" placeholder="Enter password")
button.btn.btn-success#login-submit-btn(type='submit') Sing in
button.btn.btn-outline-primary#logins-singup-btn(type='button') sing up
#login-and-singup-container-2.login-and-singup-container.my-5
.error-images.mb-3
img(src="images/error icon.png", alt="")
h1 Error !
span#error-msg Please Enter Corrext Email
form#singup-form(method='post' action='/loginandsingup')
.mb-3
label.form-label(for='username') User name
input#username.form-control(name='username' type='text' )
.mb-3
label.form-label(for='email') Email
input#email.form-control(name='email' type='Email')
.mb-3
label.form-label(for='mobilenumber') Enter number
input#mobilenumber.form-control(name='mobilenumber' type='number')
.mb-3
label.form-label(for='password') Enter New Password
input#password.form-control(name='password' type='password')
.mb-3
label.form-label(for='confirmpassword') Confirm Password
input#confirmpassword.form-control(name='confirmpassword' type='password')
.form-check.login-checkbox-container
input.bg-danger.border-danger#tandcCheckbox.form-check-input(name='tandcCheckbox' type='checkbox' checked)
label.form-check-label.m-0(for='tandcCheckbox') Agree To Our
a.text-danger Terms And Conditions
.form-check.login-checkbox-container
input.border-danger.form-check-input#upcoming-notification(name='offersmail' type='checkbox')
label.form-check-label.m-0(for='exampleCheck1') recieve upcomimg offers and events mails
button.btn.btn-success#new-user-submit-btn(type='submit') Submit
button.btn.btn-outline-primary#signups-login-btn(type='button') Login
script(type='text/javascript' src='js/loginandsingup.js')
script(
src="https://cdn.jsdelivr.net/npm/#popperjs/core#2.10.2/dist/umd/popper.min.js",
ntegrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB",
crossorigin="anonymous"
)
script(
src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.min.js",
integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13",
crossorigin="anonymous"
)
Output from the locally hosted website, on terminal
[nodemon] restarting due to changes...
[nodemon] starting `node app.js`
Debugger listening on ws://127.0.0.1:55622/66b83ad8-4e15-4359-9d7b-1d638262c70a
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
application had started successfully on port 80
database conencted successfuly
{}
**Any solution to this problem
By default forms submit as application/x-www-form-urlencoded enctype. NodeJs cant understand it by default so you need to install and configure body-parser module.
------->It's working✌️, after including the body-parser module
const express = require('express')
const router = express.Router()
var bodyParser = require('body-parser')
router.use(bodyParser.json());
router.use(bodyParser.json({ type: 'application/*+json' }))
var urlencodedParser = bodyParser.urlencoded({ extended: false })
router.post('/loginandsingup', urlencodedParser, (req, res) => {
const body = req.body;
console.log(body);
res.json({ message: req.body.username });
})
module.exports = router;
I have created a contact form and trying to use nodemailer to send the message to my email, but not sure where is the issue.
I created a server.js and put it in the main folder while Mailer.js that contain the form in components
I am not sure how the server know that I want to use the form
this is my first project on React and I think I still don't understand some basics of React
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', (req, res) => {
const output = `
<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>
`;
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL, // generated ethereal user
pass: process.env.PASSWORD // generated ethereal password
},
tls:{
rejectUnauthorized:false
}
});
// setup email data with unicode symbols
let mailOptions = {
from: process.env.EMAIL, // sender address
to: email, // list of receivers
subject: 'Node Contact Request', // Subject line
text: 'Hello world?', // plain text body
html: output // html body
};
// send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
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...'));
This is the form
import React from 'react';
import "./Mailer.scss";
const Mailer = () =>{
return (
<div className="container">
<div className="section ContactPage">
<div className="ContactPage-banner">
<h1 className="ContactPage-banner__title">Contact Us</h1>
</div>
<div className="ContactPage-content">
<form method="POST" className="form" action="send">
<div className="row">
<label className="labels">Name</label>
<input type="text" name="name" className="input"/>
</div>
<div className="row">
<label className="labels">Email</label>
<input type="email" name="email" className="input"/>
</div>
<div className="row">
<label className="labels">Message</label>
<textarea name="message" rows='4' className="input"/>
<input type="submit" value="Send"/>
</div>
</form>
</div>
</div>
</div>
);
};
export default Mailer;
this is what I get when I click on SEND
From what I could gather, you're posting to the wrong URL.
In your server app, you create a post handler for /send
However, in your React App, you post to /xxxxx/send (You obscured the xxxxx part)
I advise that you replace your
<form method="POST" className="form" action="send">
With
<form method="POST" className="form" action="http://127.0.0.1:3000/send">
And try again
I recently deployed an app to heroku. The client side works, I can view my page and navigate it. But when I send any request to the server i get:
Failed to load resource: the server responded with a status of 404 (Not Found)
Uncaught (in promise) ReferenceError: axios is not defined
In local it all works fine, but for production I changed the URL in my axios requests to match the new Heroku URL.
But for some reason in Heroku production it won't load axios?
https://reviewer-jp.herokuapp.com/ is the link if you wanna see the app and the exact messages.
Package.json
{
"name": "sql-with-orm-node",
"version": "1.0.0",
"description": "",
"main": "express.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node express.js",
"heroku-postbuild": "cd client && npm install && npm run build"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"axios": "0.19.2",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"sequelize": "^5.10.1",
"sqlite3": "^4.0.9"
}
}
Main.js file
// Elements
const movieTitle = document.querySelector('#title');
const movieRuntime = document.querySelector('#runtime');
const movieRating = document.querySelector('#rating');
const movieReview = document.querySelector('#review');
const createMovieBtn = document.querySelector('#create-btn');
const closeBtn = document.querySelector('#close');
const notification = document.querySelector('#notification');
const errorDiv = document.querySelector('#error-div');
// Close notification on click
closeBtn.addEventListener('click', (e) => {;
notification.style.display = 'none';
})
// Create movie
createMovieBtn.addEventListener('click', async(e) => {
e.preventDefault()
// Reset the notification bar to be displayed again
resetNotification();
let title = movieTitle.value;
let runtime = movieRuntime.value;
let rating = movieRating.value;
let review = movieReview.value;
const validMovieCreationHTML = validateHTML(title, runtime, rating, review, e);
//Checks to see if HTML is valid to be posted.
if(validMovieCreationHTML) {
// Extract input values from the form element and send them as a post request
// Use http://localhost:5000 for development
await axios.post('https://reviewer-jp.herokuapp.com/movies/create', {
title,
runtime,
rating,
review
})
.then((response) => {
// Display movie created notification
showNotification(response);
clearInputValues();
})
.catch( err => errorDiv.innerHTML = err ); // Display error message
}
});
express.js file
'use strict';
const cors = require('cors');
const express = require('express');
const routes = require('./routes');
const bodyParser = require('body-parser');
// Create the Express app.
const app = express();
// Enable All CORS Requests
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
// Setup request body JSON parsing.
app.use(express.json());
// Heroku deployment
app.use(express.static(__dirname + '/client'));
// Setup a friendly greeting for the root route.
app.get('/', (req, res) => {
res.json({
message: 'Welcome, please create a movie instance!',
});
});
// Add routes.
app.use('/movies', routes);
// Send 404 if no other route matched.
app.use((req, res) => {
res.status(404).json({
message: 'Route Not Found',
});
});
// Setup a global error handler.
app.use((err, req, res, next) => {
console.error(`Global error handler: ${JSON.stringify(err.stack)}`);
res.status(500).json({
message: err.message,
error: process.env.NODE_ENV === 'production' ? {} : err,
});
});
// Set our port.
app.set('port', process.env.PORT || 5000);
// Start listening on our port.
const server = app.listen(app.get('port'), () => {
console.log(`Express server is listening on port ${server.address().port}`);
});
index.html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://kit.fontawesome.com/2a0c07254d.js" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="./css/main.css"></link>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#300;400;500;700&display=swap" rel="stylesheet">
<title>Document</title>
</head>
<body>
<div id="notification">
<btn id="close"> Close </btn>
</div>
<h1>Reviewer</h1>
<div id="error-div"></div>
<form autocomplete="on" class="create-movie-form" action="submit">
<label for="title">Movie Title:</label>
<input type="text" name="title" alt="Movie title" id="title" placeholder="Movie Title" />
<label for="runtime">Movie Runtime:</label>
<input type="text" name="runtime" alt="Movie Runtime" id="runtime" placeholder="Runtime" />
<label for="rating">Movie Rating (Between 1 and 10):</label>
<input type="text" name="rating" alt="Movie Rating" id="rating" placeholder="What's your rating for this movie?" />
<label for="review">Movie Review:</label>
<textarea name="review" alt="Movie Review" id="review" rows="4" cols="50" placeholder="Movie review"></textarea>
<button type="submit" id="create-btn">Create movie review</button>
</form>
<form autocomplete="on" id="get-movies-form" action="submit">
<label class='search-by-title-label' for="search-for-movie-input">Search by movie title:</label>
<div class="get-movies-div">
<input type='search' name="search-for-movie-input" alt="Search input" id='movie-title-to-search-input' placeholder="Search" />
<button id="get-movie-by-name-btn">Search</button>
</div>
</form>
<button id='display-all-movies-btn'>Display All Listings</button>
<div id='movie-list'></div>
<script src="../node_modules/axios/dist/axios.min.js"></script>
<script src="functions.js"></script>
<script src="movies.js"></script>
<script src="main.js"></script>
</body>
</html>
Thank you for any help!
you have this on your app:
<script src="../node_modules/axios/dist/axios.min.js"></script>
but you should use the CDN with an url like the one provided in Here or if you use NPM as it seems.... import it as a module if you can, like this:
Main.js file
// Elements
const movieTitle = document.querySelector('#title');
const movieRuntime = document.querySelector('#runtime');
const movieRating = document.querySelector('#rating');
const movieReview = document.querySelector('#review');
const createMovieBtn = document.querySelector('#create-btn');
const closeBtn = document.querySelector('#close');
const notification = document.querySelector('#notification');
const errorDiv = document.querySelector('#error-div');
const axios = require('axios');
otherwise it will never find the ..node_modules/axios.... folder because it is not accesible from the front end, it is on your server.
I'm relatively new at web development and in the phase where you do as many projects as you can for practice. I have a simple website for my profile and two script tags at the bottom of my index page right before the closing body tag.
<script type="text/javascript" src="js/scroll.js"></script>
<script type="text/javascript" src="js/app.js"></script>
They are kept in a folder called "js" and have the .js type. The app.js has my js for a contact form and the scroll.js is empty for now.
I get a bunch of errors in the console in Chrome:
GET http://localhost:3000/js/scroll.js net::ERR_ABORTED 404 (Not Found)
localhost/:127 GET http://localhost:3000/js/app.js net::ERR_ABORTED 404 (Not Found)
localhost/:126 GET http://localhost:3000/js/scroll.js net::ERR_ABORTED 404 (Not Found)
:3000/#about:1 Refused to execute script from 'http://localhost:3000/js/scroll.js'
because its MIME type ('text/html') is not executable, and strict MIME type checking is
enabled.
localhost/:127 GET http://localhost:3000/js/app.js net::ERR_ABORTED 404 (Not Found)
:3000/#about:1 Refused to execute script from 'http://localhost:3000/js/app.js' because
its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
I would really appreciate any help. This is also my first time asking a question here so thanks for your patience.
UPDATE:
Thank you ll for your help - I learned a lot. I'm having a related issue now. I moved app.js and scroll.js to the correct folder and got it, however now everyday I try to run the server, it seems to be going to the wrong directory.
ex:Failed to lookup view "contact" in views directory "C:\Users\eh653\desktop\profile\public" then the next day Failed to lookup view "contact" in views directory "C:\Users\eh653\desktop\profile\public\views".
Here is my 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', (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>
`;
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: 'mail.host.com',
port: 465,
secure: true, // true for 465, false for other ports
auth: {
user: 'example#example.com', // generated ethereal user
pass: 'password' // generated ethereal password
},
tls: {
rejectUnauthorized: false
}
});
// setup email data with unicode symbols
let mailOptions = {
from: '"Emily Hickey" <info#emilyrhickey.com>', // sender address
to: 'emilyrhickey89#gmail.com', // list of receivers
subject: 'Node Contact Request', // Subject line
text: 'Hello world?', // plain text body
html: output // html body
};
// send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
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...'));
I'm not sure why it keeps changing each day to another folder. Again, thanks for any help.