POST requests return null. The req.body..... values are undefined. I tried to verify it arrives to the server in JSON format, but
i am not sure I am doing it in a right way.... :-(
Thanx a lot for help, amigos!
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const bodyParser = require('body-parser');
const cors = require("cors");
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
var app = express();
app.set('view engine', 'ejs')
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(bodyParser.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
const { MongoClient } = require("mongodb");
const uri = "mongod...the string is ok....y";
const client = new MongoClient(uri);
const database = client.db('holdocsDB');
const records = database.collection('records');
app.post("/users", async (req, res) => {
console.log('hola pooost');
console.log("req.body.age: " + req.body.age);
try {
// create a document to insert
const newRecord = {
firstName: req.body.firstName,
age: req.body.age
}
const result = await records.insertOne(newRecord);
console.log(`A document was inserted with the _id: ${result.insertedId}`);
// } finally {
// await client.close();
// }
} catch {
(e) => (console.error(e));
}
});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.json('error');
});
module.exports = app;
When I hardcode some values to be posted in express POST route (instead of extracting the values from req.body) - it works well.
function RecordSearchBar() {
const [form, setForm] = useState({
firstName: "",
age: 0
});
// const navigate = useNavigate();
function updateForm(value) {
return setForm((prev) => {
return { ...prev, ...value };
});
}
async function onSubmit(e) {
e.preventDefault();
const newPerson = { ...form };
await fetch("http://localhost:3001/users/add", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(newPerson),
})
.catch(error => {
window.alert(error);
return;
});
setForm({ firstName: "", age: ""});
// navigate("/users");
}
return (
<>
<h2>Search records:</h2>
<form onSubmit={onSubmit} id='search-form'>
<div className="form-group">
<label htmlFor="firstName">First name</label>
<input
type="text"
className="form-control"
id="name"
value={form.name}
onChange={(e) => updateForm({ name: e.target.value })}
/>
</div>
<div className="form-group">
<label htmlFor="age">Age</label>
<input
type="number"
className="form-control"
id="position"
value={form.position}
onChange={(e) => updateForm({ position: e.target.value })}
/>
</div>
<div className="form-group">
<input
type="submit"
value="Add record"
className="btn btn-primary"
/>
</div>
</form>
</>
Solved! I had to correct the type conversion of request body using JSON.parse() and JSON.stringify():
app.post("/users", async (req, res) => {
console.log("req.body: " + JSON.stringify(req.body));
let newRecordStringified = JSON.stringify(req.body)
try {
// create a document to insert
const newRecord = {
firstName: req.body.firstName,
age: req.body.age
// firstName: "Mamile",
// age: 33
}
const result = await records.insertOne(JSON.parse(newRecordStringified));
console.log(`A document was inserted with the _id: ${result.insertedId}`);
// } finally {
// await client.close();
// }
} catch {
(e) => (console.error(e));
}
})
Related
I am making the payment app with stripe. (base on the stripe repo)
I made server.js with express.
When I clicked the pay button is clicked, console shows xhr.js:177 POST http://localhost:3000/[object%20Object] 404 (Not Found)
this error.
server.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const path = require('path');
if (process.env.NODE_ENV !== 'production') require('dotenv').config();
const stripe = require('stripe')(process.env.SECRET_KEY);
const app = express();
const port = process.env.PORT || 5000;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
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.listen(port, error => {
if (error) throw error;
console.log('server running on port' + port);
});
app.post('/pay', async (req, res) => {
if (req.method === 'POST') {
try {
const { amount } = req.body;
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency: 'usd',
});
res.status(200).send(paymentIntent.client_secret);
} catch (err) {
res.status(500).json({ statusCode: 500, message: err.message });
}
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Method Not Allowed');
}
});
this is the checkout form
Checkoutform.js
import React, { useState } from 'react';
import { CardElement, useStripe, useElements } from '#stripe/react-stripe-js';
import BillingDetailsFields from './BillingDetailForm';
import axios from 'axios';
import styled from 'styled-components';
import payment_intents from './api/payment_intents';
const CheckoutForm = ({ price, onSuccessfulCheckout }) => {
const [isProcessing, setProcessingTo] = useState(false);
const [checkoutError, setCheckoutError] = useState();
const stripe = useStripe();
const elements = useElements();
const handleCardDetailsChange = ev => {
ev.error ? setCheckoutError(ev.error.message) : setCheckoutError();
};
const handleFormSubmit = async e => {
e.preventDefault();
const billingDetails = {
name: e.target.name.value,
email: e.target.email.value,
address: {
city: e.target.city.value,
line1: e.target.address.value,
state: e.target.state.value,
postal_code: e.target.zip.value,
},
};
setProcessingTo(true);
const cardElement = elements.getElement('card');
try {
const { data: clientSecret } = await axios.post(
{ payment_intents },
{
amount: price,
}
);
console.log(clientSecret);
const paymentMethodReq = await stripe.createPaymentMethod({
type: 'card',
card: cardElement,
billing_details: billingDetails,
});
if (paymentMethodReq.error) {
setCheckoutError(paymentMethodReq.error.message);
setProcessingTo(false);
return;
}
const { error } = await stripe.confirmCardPayment(clientSecret, {
payment_method: paymentMethodReq.paymentMethod.id,
});
if (error) {
setCheckoutError(error.message);
setProcessingTo(false);
return;
}
onSuccessfulCheckout();
} catch (err) {
setCheckoutError(err.message);
}
};
const cardElementOpts = {
hidePostalCode: true,
};
return (
<form onSubmit={handleFormSubmit}>
<div>
<CheckoutTitle>Pay with</CheckoutTitle>
<BillingDetailsFields />
</div>
<div>
<CardElementContainer>
<CardElement
option={cardElementOpts}
onChange={handleCardDetailsChange}
/>
</CardElementContainer>
</div>
<div>
<PayBtn disabled={isProcessing || !stripe}>
{isProcessing ? 'Processing...' : `Confirm and Pay`}
</PayBtn>
</div>
</form>
);
};
I think there is an issue with the app.post('/pay', async (req, res) => {}
But I really don't know what is the problem.
I am building a MERN app and when I try to console.log(req.file) on the server I get undefined. I've checked the multer github page and other SO articles, but I still haven't been able to figure it out using React hooks and jsx. I'm newish to SO so, I will add edits since I can't comment yet.
Here is a link to the branch in GitHub if you want to see all the files. https://github.com/BenjDG/puzzle-gallery/tree/so
I'm new to multer and react so any help is appreciated.
Here is my code:
server\controllers\puzzleController.js
const multer = require('multer');
const upload = multer({ dest: './uploads'});
const db = require('../models');
const fs = require('fs');
const type = upload.single('picFile');
// Defining methods for the puzzleController
module.exports = {
findAll: function (req, res) {
db.Puzzle
.find(req.query)
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
save: (type, function (req, res) {
// console.log(req);
console.log(req.file);
console.log(req.body);
res.sendStatus(200);
}),
remove: function (req, res) {
db.Puzzle
.findById({ _id: req.params.id })
.then(dbModel => dbModel.remove())
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
}
};
client\src\components\gallery\index.js
import React, { useState } from 'react';
import './styles.css';
import API from '../../services/API';
export default function Gallery () {
const [picFile, setPicFile] = useState();
const handleGetClick = async () => {
API.findAll()
.then(res => {
console.log(res)
})
.catch(err => console.error(err))
}
const handleUploadClick = async (e) => {
e.preventDefault();
// console.log(picFile);
// create new formData instance
const bodyFormData = new FormData();
// append single file to formData instance
bodyFormData.append('picFile', picFile.selectedFile);
// log items in formData object
for (const element of bodyFormData) {
console.log(element);
}
// send formData obj to axios function
API.save(bodyFormData)
.then(res => {
//console.log(res)
})
.catch(err => console.error(err))
}
const onFileChange = (e) => {
console.log(`e.target.files[0]`, e.target.files[0])
setPicFile({ selectedFile: e.target.files[0] });
}
return (
<div>
<h1>My Puzzle Gallery</h1>
<form encType='multipart/form-data'>
<input type='file' name='picFile' onChange={onFileChange} />
<br />
<br />
<button onClick={handleUploadClick}>Upload a picture</button>
</form>
<br />
<br />
<button onClick={handleGetClick}>Get pictures</button>
<br />
<br />
<img src='https://placekitten.com/640/360' alt='kitten' />
</div>
);
}
client\src\services\API.js
import axios from 'axios';
const API = {
login: (username, password) => {
const obj = {
username: username,
password: password
};
return axios.post('/api/auth/login', obj);
},
register: (username, password) => {
const obj = {
username: username,
password: password
};
return axios.post('/api/auth/register', obj);
},
logout: function () {
return axios.get('api/auth/logout');
},
save: function (form) {
return axios.post('api/puzzle/', form).catch(err=>console.error(err));
},
findAll: function () {
return axios.get('api/puzzle/');
},
}
export default API;
server\routes\api\puzzle\index.js
const router = require('express').Router();
const puzzleController = require('../../../controllers/puzzleController');
// Matches with '/api/puzzle'
router.route('/')
.get(puzzleController.findAll)
.post(puzzleController.save);
// Matches with '/api/books/:id'
router.route('/delete/:id')
.delete(puzzleController.remove);
module.exports = router;
server\server.js
const path = require('path');
const express = require('express');
const passport = require('./config/passport');
const mongoose = require('mongoose');
const cors = require('cors');
const session = require('express-session');
const helmet = require('helmet');
const morgan = require('morgan');
const corsOptions = require('./config/cors.js');
const routes = require('./routes');
const { v1: uuidv1 } = require('uuid');
// console.log(uuidv1());
const PORT = process.env.PORT || 3001;
const app = express();
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost/puzzlegallery', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false
});
mongoose.set("useCreateIndex", true);
// Define middleware here
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(helmet({ contentSecurityPolicy: false }));
app.use(session({ secret: 'sassy', resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(cors(corsOptions));
app.use(morgan('dev'));
app.use(routes);
// for Reactjs ##################
// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === 'production') {
app.use(express.static('client/build'));
}
// #################################################
if (process.env.NODE_ENV === 'production') {
app.get('*', (_, res) => {
res.sendFile(path.join(__dirname, '../client/build/index.html'));
});
}
app.listen(PORT, (err) => {
if (err) throw err;
console.log(
`🌎 Server is Ready and Listening on http://localhost:${PORT}`
); // eslint-disable-line no-console
});
EDIT:
This seemed to work. Thanks again!!
const path = require('path');
const router = require('express').Router();
const puzzleController = require('../../../controllers/puzzleController');
const multer = require('multer');
const { v1: uuidv1 } = require('uuid');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.join(__dirname, '../../../../tmp/my-uploads'))
},
filename: function (req, file, cb) {
cb(null, uuidv1())
}
})
const upload = multer({ storage: storage });
// Matches with '/api/puzzle'
router.route('/')
.get(puzzleController.findAll)
// Matches with '/api/books/:id'
router.route('/delete/:id')
.delete(puzzleController.remove);
router.use(upload.single('picFile'));
router.route('/')
.post(puzzleController.save);
module.exports = router;
you cannot call the middleware inside the save function like this.
I cloned your repo and added the following code in server.js and it's working fine and I got the value in the req.file.
const multer = require('multer');
const upload = multer({ dest: 'uploads/'});
app.post('/api/puzzle/', upload.single('pictureFile'),(req,res,next)=>{
console.log("req.file22222222", req.file);
})
I am trying to update local database in mongodb. In my project I want to update my data here is the code.
second part is the edit part that i use to redirect my update data. It don't show any error so i can not find any problem to fix.All project in node.js, and use handelbar template , mongoose as database
:
const express = require('express')
const app = express()
const exphbs = require('express-handlebars');
const mongoose = require('mongoose')
const path = require('path')
const Idendity = require('./db/db.js')
const methodOverride = require('method-override')
app.use(methodOverride('_method'))
app.use(express.static( __dirname + "/public"));
app.use(express.urlencoded({
extended: false
}))
app.engine('.hbs', exphbs({
extname: '.hbs'
}))
app.set('view engine', '.hbs')
async function connectDB() {
try {
await mongoose.connect('mongodb://localhost:27017/Idendity', {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true
})
console.log('database is connected')
} catch (error) {
console.log(error)
}
}
connectDB()
app.get('/', async (req, res) => {
const idendity = await Idendity.find()
const idendities = {
data: idendity.map(element => {return{id:element._id,name:element.name,email:element.email,profession:element.profession}} )
}
//console.log(idendities.data)
res.render('home', {
ID: idendities.data,
title: 'Contact App'
})
})
app.post('/', async (req, res) => {
const idendity = new Idendity({
...req.body
})
await idendity.save()
res.redirect('/')
})
app.get('/edit/:id',async (req,res)=>{
const id = req.params.id
const idendity = await Idendity.findById(id)
const contex = {name:idendity.name,email:idendity.email,profession:idendity.profession}
if(idendity){
res.render('edit',{
idendity:contex
})
}else{
res.send('404 not found')
}
})
app.put('/edit/:id',async (req,res)=>{
const id = req.params.id
const value = req.body
const newIdendity = await Idendity.findByIdAndUpdate(id,value,{ useFindAndModify:false})
console.log(value)
if(newIdendity){
res.redirect(`/edit/${id}`)
}else{
res.send('404 not found')
}
})
app.listen(8000, () => {
console.log('port is listening')
})
//////////////////////////////////////////////////////
<div class="container">
{{#with idendity}}
<form action="/?_method=PUT" method="POST">
<label for="name">name</label><br>
<input type="text" name="name" id="name" value={{name}}><br>
<label for="email">email</label><br>
<input type="text" name="email" id="email" value={{email}}><br>
<label for="profession">profession</label> <br>
<input type="text" name="profession" id="profession" value={{profession}}><br>
<button class="btn btn-primary my-3">add</button>
</form>{{/with}}
cancel
</div>
you can send put request to the given route because you don't have any put method attached to that route you are trying to access.
you have to have an
app.put("/",async(req,res)=>{
//code
})
or you can use
// this will be accessible by all HTTP methods
app.use("/",async(req,res)=>{
//code
})
in your code to be able to send a put request to the server.
I am trying to create e registration for a new user with profile picture upload. But my form data is not passing to the route. I have added body-parser middleware but still, it seems something is wrong and I cannot find the reason.
Error:
D:\temp_project\smpms\routes\users.js:118
if (err) throw err;
^
Error: Illegal arguments: undefined, string
at _async (D:\temp_project\smpms\node_modules\bcryptjs\dist\bcrypt.js:214:46)
at Object.bcrypt.hash (D:\temp_project\smpms\node_modules\bcryptjs\dist\bcrypt.js:220:13)
at D:\temp_project\smpms\routes\users.js:117:28
at Immediate.<anonymous> (D:\temp_project\smpms\node_modules\bcryptjs\dist\bcrypt.js:153:21)
at processImmediate (internal/timers.js:456:21)
[nodemon] app crashed - waiting for file changes before starting...
app.js
const express = require("express");
const expressLayouts = require("express-ejs-layouts");
const mongoose = require("mongoose");
const passport = require("passport");
const flash = require("connect-flash");
const session = require("express-session");
const multer = require('multer');
const path = require('path');
var dotenv = require('dotenv').config();
const bodyParser = require('body-parser');
const app = express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(express.static("public"));
// Passport Config
require("./config/passport")(passport);
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(db, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log("MongoDB Connected"))
.catch((err) => console.log(err));
// EJS
app.use(expressLayouts);
app.set("view engine", "ejs");
// Express body parser
app.use(express.urlencoded({ extended: true }));
// Express session
app.use(
session({
secret: "secret",
resave: true,
saveUninitialized: true,
})
);
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Connect flash
app.use(flash());
// Global variables
app.use(function (req, res, next) {
res.locals.success_msg = req.flash("success_msg");
res.locals.error_msg = req.flash("error_msg");
res.locals.error = req.flash("error");
next();
});
// Routes
app.use("/", require("./routes/index.js"));
app.use("/users", require("./routes/users.js"));
const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`Server started on port ${PORT}`));
User.js - User model
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
avatar:{
type:String,
required:true
},
date: {
type: Date,
default: Date.now
}
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
User.js route:
const express = require("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const passport = require("passport");
const multer = require('multer');
const path = require('path');
const bodyParser = require('body-parser')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
// Load User model
const User = require("../models/User");
const {forwardAuthenticated} = require("../config/auth");
// Login Page
router.get("/login", forwardAuthenticated, (req, res) => {
res.render("login", {title: "Login", layout: "layout"});
});
// Register Page
router.get("/register", forwardAuthenticated, (req, res) => {
res.render("register", {title: "Register", layout: "layout"});
});
// Register
router.post("/register", (req, res) => {
//const {name, email, password, password2||avatar} = req.body;
const name = req.body.name
const email = req.body.email
const password = req.body.password;
const password2 = req.body.password2;
const avatar = req.body.avatar;
let errors = [];
//
// if (!name || !email || !password || !password2) {
// errors.push({msg: "Please enter all fields"});
// }
// if (password && password.length < 6) {
// errors.push({msg: "Password must be at least 6 characters"});
// }
// if (password != password2) {
// errors.push({msg: "Passwords do not match"});
// }
if (errors.length > 0) {
res.render("register", {
errors,
name,
email,
password,
password2,
title: "Register",
layout: "Layout",
});
} else {
User.findOne({email: email}).then((user) => {
if (user) {
errors.push({msg: "Email already exists"});
res.render("register", {
errors,
name,
email,
password,
password2,
title: "Register",
layout: "Layout",
});
} else {
const newUser = new User({
name,
email,
password,
});
//Set The Storage Engine
const storage = multer.diskStorage({
destination: './public/uploads/',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + newUser._id + path.extname(file.originalname));
}
});
// Init Upload
const upload = multer({
storage: storage,
limits: {fileSize: 1000000},
fileFilter: function (req, file, cb) {
checkFileType(file, cb);
}
}).single('avatar');
// Check File Type
function checkFileType(file, cb) {
// Allowed ext
const filetypes = /jpeg|jpg|png|gif/;
// Check ext
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
// Check mime
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Error: Images Only!');
}
}
console.log(newUser);
newUser.avatar = storage;
console.log(newUser);
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser
.save()
.then((user) => {
req.flash(
"success_msg",
"You are now registered and can log in"
);
res.redirect("/users/login");
})
.catch((err) => console.log(err));
});
});
}
});
}
});
// Login
router.post("/login", (req, res, next) => {
passport.authenticate("local", {
successRedirect: "/dashboard",
failureRedirect: "/users/login",
failureFlash: true,
})(req, res, next);
});
// Logout
router.get("/logout", (req, res) => {
req.logout();
req.flash("success_msg", "You are logged out");
res.redirect("/users/login");
});
module.exports = router;
Register.ejs is the file where the form is not passing data to the route.
<div class="row mt-5">
<div class="col-md-6 m-auto">
<div class="card card-body">
<h1 class="text-center mb-3">
<i class="fas fa-user-plus"></i> Register
</h1>
<% include ./partials/messages %>
<%= typeof msg != 'undefined' ? msg : '' %>
<form action="/users/register" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="name">Name</label>
<input
type="name"
id="name"
name="name"
class="form-control"
placeholder="Enter Name"
value="<%= typeof name != 'undefined' ? name : '' %>"
/>
</div>
<div class="form-group">
<label for="email">Email</label>
<input
type="email"
id="email"
name="email"
class="form-control"
placeholder="Enter Email"
value="<%= typeof email != 'undefined' ? email : '' %>"
/>
</div>
<div class="form-group">
<label for="password">Password</label>
<input
type="password"
id="password"
name="password"
class="form-control"
placeholder="Create Password"
value="<%= typeof password != 'undefined' ? password : '' %>"
/>
</div>
<div class="form-group">
<label for="password2">Confirm Password</label>
<input
type="password"
id="password2"
name="password2"
class="form-control"
placeholder="Confirm Password"
value="<%= typeof password2 != 'undefined' ? password2 : '' %>"
/>
</div>
<div class="form-group">
<label for="">Profile Picture</label>
<input type="file" name="avatar" id="" class="form-control file-path validate">
</div>
<button type="submit" class="btn btn-primary btn-block">
Register
</button>
</form>
<p class="lead mt-4">Have An Account? Login</p>
</div>
</div>
</div>
It seems that you aren't using multer correctly. Usually multer configuration is set globally and above all the APIs and then we pass that middleware function generated by multer to that specific API which has multipart/form-data header in its request. You have to move your configuration for multer, outside of your API, then pass the upload as a middleware to your API. Also from your clientside, you have to pass data properly. A good answer about sending JSON alongside the File with FormData object can be found here. Also you can add text fields in FormData object from clientside and receive it as object in req.body according to multer documentation. Just make sure you're passing data from clientside to server correctly. Here is your router with multer middleware:
const express = require("express");
const router = express.Router();
const fs = require('fs');
const bcrypt = require("bcryptjs");
const passport = require("passport");
const multer = require('multer');
const path = require('path');
const bodyParser = require('body-parser')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
// Load User model
const User = require("../models/User");
const { forwardAuthenticated } = require("../config/auth");
// Login Page
router.get("/login", forwardAuthenticated, (req, res) => {
res.render("login", { title: "Login", layout: "layout" });
});
// Register Page
router.get("/register", forwardAuthenticated, (req, res) => {
res.render("register", { title: "Register", layout: "layout" });
});
const storage = multer.diskStorage({
destination: './public/uploads/'
});
// Init Upload
const upload = multer({
storage: storage,
limits: { fileSize: 1000000 },
fileFilter: function (req, file, cb) {
checkFileType(file, cb);
}
});
// Check File Type
function checkFileType(file, cb) {
// Allowed ext
const filetypes = /jpeg|jpg|png|gif/;
// Check ext
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
// Check mime
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Error: Images Only!');
}
}
// Register
router.post("/register", upload.single('avatar'), (req, res) => {
//const {name, email, password, password2||avatar} = req.body;
const name = req.body.name
const email = req.body.email
const password = req.body.password;
const password2 = req.body.password2;
let errors = [];
//
// if (!name || !email || !password || !password2) {
// errors.push({msg: "Please enter all fields"});
// }
// if (password && password.length < 6) {
// errors.push({msg: "Password must be at least 6 characters"});
// }
// if (password != password2) {
// errors.push({msg: "Passwords do not match"});
// }
if (errors.length > 0) {
res.render("register", {
errors,
name,
email,
password,
password2,
title: "Register",
layout: "Layout",
});
} else {
User.findOne({ email: email }).then((user) => {
if (user) {
errors.push({ msg: "Email already exists" });
res.render("register", {
errors,
name,
email,
password,
password2,
title: "Register",
layout: "Layout",
});
} else {
const directory = "/images/";
const newUser = new User({
name,
email,
password,
avatar: `./public/uploads/${req.file}`
});
const filePath = path.join(__dirname, "../public/uploads/");
fs.rename(filePath + req.file.filename, req.file.fieldname + '-' + newUser._id + path.extname(req.file.originalname), (error) => {
if (error) {
return console.log(`Error: ${error}`);
}
});
newUser.avatar = 'public/uploads/' + req.file.fieldname + '-' + newUser._id + path.extname(req.file.originalname);
console.log(newUser);
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser
.save()
.then((user) => {
req.flash(
"success_msg",
"You are now registered and can log in"
);
res.redirect("/users/login");
})
.catch((err) => console.log(err));
});
});
}
});
}
});
// Login
router.post("/login", (req, res, next) => {
passport.authenticate("local", {
successRedirect: "/dashboard",
failureRedirect: "/users/login",
failureFlash: true,
})(req, res, next);
});
// Logout
router.get("/logout", (req, res) => {
req.logout();
req.flash("success_msg", "You are logged out");
res.redirect("/users/login");
});
module.exports = router;
It will save your file without any problem (if your configuration about directory and filename was okay).
I want to send a flash message in a login Form. When the username or the password is wrong, send a flash message username/password incorrect it not showing.
i try to debug console log local.error_message, that's success show username/password incorrect when i entry username and password wrong. when i comment debug code and implement to htmltemplate its not working well.
pages.js
const express = require('express');
const User = require('./login');
const htmlTemplate = (error_message) => {
return `
<!doctype html>
<html class="no-js" lang="en">'
<body>
<form action="/login" method="POST" class="login-background">
<img class="img-responsive" alt="logo" src="img/logo.png">
<h5>LOGIN</h5>
${error_message ? `<div class="alert alert danger">${error_message}</div>` : ""}
<input type="text" name="username" class="form-control input-lg" placeholder="Username">
<input type="password" name="password" class="form-control input-lg" placeholder="Password">
<button type="submit" value="login" class="btn btn-primary">Masuk</button>
</form>
</body>
</html>
`};
//Get the index page
const getIndexPage = ('/', (req, res, next) => {
let user = req.session.user;
let login = "";
if (user) {
res.redirect('/dashboard');
return;
}
res.send(htmlTemplate(login))
});
//get Homepage
const getHome = ('/home', (req, res, next) => {
let user = req.session.user;
if (user) {
res.render('/dashboard', { opp: req.session.opp, name: user.nama });
return;
}
res.redirect('/');
});
const postLogin = ('/login', (req, res, next) => {
user.login(req.body.username, req.body.password, function (result) {
if (result) {
req.session.user = result;
req.session.opp = 1;
res.redirect('/dashboard');
} else {
req.flash('error_message', 'Username/password incorrect!');
res.locals.error_message = req.flash('error_message');
// var message = res.locals.error_message = req.flash('error_message');
// console.log(message);
res.redirect('/dashboard');
}
})
});
module.exports = {
getIndexPage,
postLogin,
getHome
};
index.js
const express = require("express");
const mysql = require("mysql");
const bodyParser = require("body-parser");
const session = require('express-session');
const cookieParser = require('cookie-parser');
const flash = require('connect-flash');
const app = express();
const port = 3000;
const login = require("./pages");
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
app.use(cookieParser());
//session
app.use(session({
secret: 'ghhft',
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 60 * 1000 * 30
}
}));
//flash
app.use(flash());
const onlyLoggedinUser = next => (req, res) => {
console.log(`onlyLoggedinUser ${req.path}`)
const level = getUserContext(req).level
if (level !== TYPE_ADMIN && level !== TYPE_MANAGER) {
res.redirect("/loggout")
return;
}
next(req, res)
}
const onlyLoggedoutUser = next => (req, res) => {
const level = getUserContext(req).level
if (level !== TYPE_UNKNOWN) {
res.redirect("/dashboard")
return;
}
next(req, res)
}
app.get("/", onlyLoggedoutUser(login.getIndexPage));
app.post("/login", onlyLoggedoutUser(login.postLogin));
app.get("/home", onlyLoggedinUser(login.getHome));
helper.js
const TYPE_UNKNOWN = "UNKNOWN" // 0
const TYPE_ADMIN = "ADMIN" // 1
const TYPE_MANAGER = "MANAGER" // 2
function getUserContext(req) {
const user = _.get(req, "session.user", false)
let level = TYPE_UNKNOWN
if (user === false) return {
level,
username: "",
}
if (user.level === "1")
level = TYPE_ADMIN
if (user.level === "2")
level = TYPE_MANAGER
return {
level,
username: user.username
}
}
can you help me solve this problem?