How to show data on frontend using Controller in Mysql - mysql

I am trying to show data on front end using controller in Angular js but unable to do so I am able to take data from database that is mysql but don't know how to show it on frontend
module.exports = function(app) {
app.post('/login', function(req, res) {
var email = req.body.email;
var password = req.body.password;
console.log(password);
if (email && password) {
connection.query('select * from user where email = ? and password = ?', [email, password], function(err, result) {
console.log(result);
if (err) res.send(err);
res.redirect('/dashboard');
});
}
});
}

Related

How i display username after login successful with set cookies using angular nodejs mysql

My login.component.ts file
How to set cookies in the code to display the username.
login Submit(){
console.log(this.userLogin.value)
this.service.LoginData(this.userLogin.value).subscribe((res)=>{
console.log(res)
this.userLogin.reset()
this.successmsg = res.message
this.Username = this.cookieService.set('username', this.Username)
})
}
I am trying to display the username but it only see me undefined.
api service file
LoginData(data:any):Observable<any>{
return this.http.post(`http://localhost:3000/login`,data)
}
dashboard(){
return this.http.get('http://localhost:3000/dashboard')
}
NodeJS file using MySQL database
app.post('/login', (req, res) => {
const username = req.body.username;
const password = req.body.password;
const query = `SELECT * FROM user WHERE username = '${username}' AND password = '${password}'`;
db.query(query, (error, result) => {
if (error) {
console.log('Error querying database:', error);
res.status(500).send('Error querying database');
} else if (result.length === 0) {
console.log('Invalid username or password');
res.status(401).send('Invalid username or password');
} else {
console.log('Login successful');
res.status(200).send({
message: 'Login successful',
username: username
});
}
});
res.cookie('username',`${username}`)
});

My Express MySQL server get crash when user input wrong data for login

When the user try to login with wrong email or password my app throw error user not found if the email is not in dB a other error then password is wrong but after few second the server get crashed with the error
"SERVER CONNECTION LOST"
I was Thing the problem come in my error handling but after many try and search i'm now block
export const getUser = (req, res) => {
const token = req.cookies.accessToken;
if (!token) return res.status(401).json("Please logging first !");
jwt.verify(token, "secretkey", (err, data) =\> {
if (err) {
return res.status(403).json("Please login first !!");
}
const q = "SELECT * FROM `Users` WHERE ID= ?";
db.query(q, [req.params.userId], (err, data) => {
if (err) return res.status(500).json("Something when wrong !!");
const { user_PassCode, ...info } = data[0];
if(data) return res.json(info);
});
});
};
//...........LOGIN START HERE...............
export const logIn = (req, res) => {
const q = "SELECT * FROM Users WHERE user_Email = ? "
db.query(q, [req.body.user_Email], (err, data) => {
if (err) res.status(500).json(err)
if(data.length === 0) res.status(404).json('user not found!')
// chech if password match to userPasscode
const checkPassword = bcrypt.compareSync(
req.body.user_PassCode,
data[0].user_PassCode
)
if(!checkPassword) return res.status(400).json('wrong password or username try again!')
const token = jwt.sign({ id: data[0].ID }, "secretkey")
const {user_PassCode, ...others} = data[0]
// if not error
res.cookie("accessToken", token, {
httpOnly: true
}).status(200).json(others)
})
}

Where to place code to show data from MySQL to Handlebars?

Goal:
I am aiming to teach myself how to use Node JS, MySQL and express.
I'm struggling to understand where to place my code for loading MySQL data into HTML.
Let me show you the whole code.
app.js
var express = require('express');
var mysql = require('mysql');
var dotenv = require('dotenv');
var path = require('path');
var cookieParser = require('cookie-parser');
dotenv.config({path: './.env'});
var app = express();
// Connection to MySQL
var db = mysql.createConnection({
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE
});
db.connect(function(error) {
if(error) {
console.log(error);
}
else{
console.log("Connected");
}
});
// Parse URL-Encoded bodies
app.use(express.urlencoded({extended: false}));
// Parse JSON bodies
app.use(express.json());
// Initialize a cookie
app.use(cookieParser());
// View engine to control HTML
app.set('view engine', 'hbs');
// Public dir
var publicDir = path.join(__dirname, './public');
app.use(express.static(publicDir));
// Define routes
app.use('/', require('./routes/pages'));
app.use('/auth', require('./routes/auth'));
app.listen(3000, function() {
console.log("Server is running on port 3000");
});
routes/pages.js
var express = require('express');
var authController = require('../controllers/auth');
var router = express.Router();
// Home
router.get("/", authController.isLoggedIn, function(req,res) {
res.render("index", {
user: req.user
});
});
// Register
router.get("/register", function(req, res) {
res.render("register");
});
// Login
router.get("/login", function(req, res) {
res.render("login");
});
// Profile
router.get('/profile', authController.isLoggedIn, function(req, res) {
if(req.user) {
res.render('profile', {
user: req.user
});
}
else {
res.redirect('login');
}
});
// Forum
router.get('/forums', authController.isLoggedIn, function(req, res) {
if(req.user) {
res.render('forums');
} else {
res.redirect('login');
}
});
// English Division //
// Premier League
router.get('/Leagues/EnglishDivision', authController.isLoggedIn, function(req, res) {
if(req.user) {
res.render('PremierLeague');
} else {
res.redirect('../../login');
}
});
module.exports = router;
routes/auth.js
var express = require('express');
var authController = require('../controllers/auth');
var router = express.Router();
// Register
router.post("/register", authController.register);
// Login
router.post("/login", authController.login);
// Logout
router.get('/logout', authController.logout);
module.exports = router;
controllers/auth.js
var mysql = require('mysql');
var jwt = require('jsonwebtoken');
var bcrypt = require('bcryptjs');
var {promisify} = require('util');
// Connection to MySQL
var db = mysql.createConnection({
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE
});
// Register function
exports.register = function(req, res) {
console.log(req.body);
var {name, email, password, passwordConfirm} = req.body;
db.query("SELECT email FROM users WHERE email = ?", [email], function(error, result) {
if(error){
console.log(error);
}
if(result.length > 0) {
return res.render('register', {
message: 'That email is already in use'
})
} else if(password !== passwordConfirm) {
return res.render('register', {
message: 'Passwords do not match'
});
}
let hashedPassword = bcrypt.hashSync(password, 8);
console.log(hashedPassword);
// Insert user details into MySQL
db.query('INSERT INTO users set ?', {name: name, email: email, password: hashedPassword, dateJoined: new Date()}, function(error, result) {
if(error) {
console.log(error);
} else {
console.log(result);
return res.render('register', {
message: 'User registered'
});
}
});
});
}
// Login function
exports.login = function(req, res) {
try {
var {email, password} = req.body;
if(!email || !password) {
return res.status(400).render('login', {
message: 'Please provide an email and password'
});
}
db.query('SELECT * FROM users WHERE email = ?', [email], async function(error, result) {
console.log(result);
if(!result.length > 0 || !(await bcrypt.compare(password, result[0].password))) {
res.status(401).render('login', {
message: 'The email or password is incorrect'
});
}
else {
var id = result[0].id;
// Create a token
var token = jwt.sign({id}, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRES_IN
});
console.log("The token is " + token);
// Create a cookie
var cookieOptions = {
expires: new Date(
Date.now() + process.env.JWT_COOKIE_EXPIRES * 24 * 60 * 60 * 1000
),
httpOnly: true
}
// Set up a cookie
res.cookie('jwt', token, cookieOptions);
res.status(200).redirect("/");
}
});
} catch (error) {
console.log(error);
}
}
// Check if logged in
exports.isLoggedIn = async function(req, res, next) {
console.log(req.cookies);
if(req.cookies.jwt){
try {
// Verify the token
var decoded = await promisify(jwt.verify)(req.cookies.jwt, process.env.JWT_SECRET);
console.log(decoded);
// Check if user exist
db.query("SELECT id, name, email, password, date_format(datejoined, '%d/%m/%Y') as dateJoined FROM users WHERE id = ?", [decoded.id], function(error, result) {
console.log(result);
// If no result
if(!result) {
return next();
}
req.user = result[0];
return next();
});
}
catch (e) {
console.log(e);
return next();
}
} else{
next();
}
}
// Logout function
exports.logout = async function(req, res) {
res.clearCookie('jwt');
res.status(200).redirect('/');
}
Question
In my .hbs file called PremierLeague I'd like to load MySQL data in HTML format. Where in the code below I need to start?
Desired goal:
This is when the user clicks into view premier league
Foreach record in MySQL I'd like to add a new card for each record. I know how to use HandleBars {{some.data}}.
I just don't get where I code the query?
Does it needs to be in a controller or can it be in in the router.get(...?
Also how do I use {{#foreach}} correctly ?
You don't need any other specific controller, the right place to code the query is actually the route itself.
But before entering the core of your question, let's talk a while about your code.
I can see you are performing connection to database more than once, you could add database dedicated controller, something like:
controllers/db.js
var mysql = require('mysql');
var dotenv = require('dotenv');
dotenv.config({path: './.env'});
// Connection to MySQL
var db = mysql.createConnection({
host: process.env.DATABASE_HOST,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE
});
function connect(done) {
db.connect(done);
}
module.exports = { db: db, connect: connect };
this let you access to the database instance from every file with just one line:
var db = require('./controllers/db').db;
than you could use the connect function in your app:
app.js
var express = require('express');
var db = require(./controllers/db);
var path = require('path');
var cookieParser = require('cookie-parser');
// set up your server
var app = express();
// Parse URL-Encoded bodies
app.use(express.urlencoded({extended: false}));
// Parse JSON bodies
app.use(express.json());
// Initialize a cookie
app.use(cookieParser());
// View engine to control HTML
app.set('view engine', 'hbs');
// Public dir
var publicDir = path.join(__dirname, './public');
app.use(express.static(publicDir));
// Define routes
app.use('/', require('./routes/pages'));
app.use('/auth', require('./routes/auth'));
// finally run your server only if you can connect to the database
db.connect(function(error) {
if(error) return console.log("Error connecting to the database:", error);
app.listen(3000, function() {
console.log("Server is running on port 3000");
});
});
you could also simplify you controllers/auth.js removing database connection stuff and using only the line to require your database controller.
Finally you can code your query:
routes/pages.js
var express = require('express');
var authController = require('../controllers/auth');
var db = require('../controllers/db').db;
var router = express.Router();
// Omissis... other routes
// Premier League
router.get('/Leagues/EnglishDivision', authController.isLoggedIn, function(req, res) {
// a good practice is first to handle possible exit cases to reduce nesting levels
if(! req.user) return res.redirect('../../login');
// this is actually the right place to perform queries
db.query('SELECT ...', [...], function(error, results) {
// once again first possible exit cases
if(error) return res.status(500).end(error.message)
res.render('PremierLeague', { results: results });
});
});
module.exports = router;
Last in your PremierLeague.hbs file you can handle the results in a #foreach directive.
Just pass your data when you render the view
router.get('/Leagues/EnglishDivision', authController.isLoggedIn, function(req, res) {
if(req.user) {
connection.query('SELECT * FROM EnglishDivision',function (err,results) {
if (err) throw err;
res.render('PremierLeague',{data: results});
});
} else {
res.redirect('../../login');
}
});
then in the .hbs file
{{#each data}}
<div class="card">
<h3>{{this.someData}}</h3>
<h2>{{this.someData}}</h2>
</div>
{{/each}}

bcrypt issue using nodejs

I have successfully encrypted the password and stored in my DB during registration. But when I am login, I am comparing the password and trying to login, during the login period my sql query is falling to read the password and I am getting hash is not defined. Please let me know where I am going wrong.
router.post('/login', function(req,res) {
var password = req.body.password;
var user_name = req.body.user_name;
var response = {};
bcrypt.compare(password, hash, function(err, res) {
db.query('select user_id,email FROM user where password = ? AND user_name = ? OR email = ?',
[hash, req.body.user_name, req.body.user_name], function (error,rows) {
if (error) {
res.json(error)
} else {
response.msg = 'Login Success';
}
});
}
});
router.post('/login', function(req,res) {
var password = req.body.password;
var user_name = req.body.user_name;
var response = {};
var hash = db.query('SELECT hash FROM user WHERE user_name = ?', [req.body.user_name]);
bcrypt.compare(password, hash, function(err, res) {
db.query('select user_id,email FROM user where password = ? AND user_name = ? OR email = ?',
[hash, req.body.user_name, req.body.user_name], function (error,rows) {
if (error) {
res.json(error)
} else {
response.msg = 'Login Success';
}
});
}
});

How to merge various MySQL queries results in a single JSON object

I'm trying to write a REST API set in NodeJS to retrieve data from my MySQL database.
Here the code:
var express = require('express');
var mysql = require('mysql');
var app = express();
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'root',
database : 'apitest',
port : '3306',
multipleStatements: true
});
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();
});
app.get('/users', function(req, res) {
connection.query('SELECT name, surname, address FROM users', function(err, results) {
if (err) throw err;
if (results) {
res.status(200).send(results);
};
});
});
app.get('/users/:userId', function (req, res) {
var userId = req.params.userId;
connection.query('SELECT * FROM users WHERE idUser = ?', [userId], function(err, result) {
if (err) throw err;
if (result) {
res.status(200).send(result);
};
});
});
app.get('/users/:userId/photos', function (req, res) {
var userId = req.params.userId;
connection.query('SELECT date, file, tags FROM photos WHERE idUser = ?', [userId], function(err, results) {
if (err) throw err;
if (results) {
res.status(200).send(JSON.stringify(results));
}
});
});
var server = app.listen(8080, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Listening on http://%s:%s', host, port);
});
Everything goes well if I use the single REST call as written above.
The problem is that I want it to work differently, so when i call /users/:userId i want to retrieve user data and the relative photos in a single, well structured, JSON response.
Eg:
{
"name" : "John",
"surname" : "Doe",
"photos" : [
{
"date" : "2015-04-19T22:00:00.000Z",
"file" : "photo1.jpg",
"tags" : "holidays, 2015"
},
{
"date" : "2015-04-19T22:00:00.000Z",
"file" : "photo2.jpg",
"tags" : "holidays, 2015, nassau"
}
]
}
I've find a workaround by modifying the /users/:userId call as mentioned above:
app.get('/users/:userId', function (req, res) {
var userId = req.params.userId;
connection.query('SELECT * FROM users WHERE idUser = ?', [userId], function(err, results1) {
if (err) throw err;
if (results1) {
connection.query('SELECT date, file, tags FROM photos WHERE idUser = ?', [userId], function(err, results2) {
if (err) throw err;
if (results2) {
results1[0].photos = results2;
res.status(200).end(JSON.stringify(results1[0]));
}
});
}
});
});
Everything seems to go well but I think is not the right way because if i want to add more information from other tables in my object i would have to nest more and more functions...
Any suggestion?
Thanks in advance.
Check out Async, or any one of the popular promise libaries(when.js, Q.js, Bluebird).
In Async, it might look something like this.
var async = require('async');
app.get('/users/:userId', function (req, res) {
var userId = req.params.userId;
async.parallel({
user: function(callback){
connection.query('SELECT * FROM users WHERE idUser = ?', [userId], callback)
},
photos: function(callback){
connection.query('SELECT date, file, tags FROM photos WHERE idUser = ?', [userId], callback)
}
},
// Final callback, with all the results
function(err, results){
//results now has {user: ..., photos: ...}
var user = results.user;
user.photos = results.photos;
res.status(200).end(JSON.stringify(user));
});
});
Adding another call is as simple as adding another function inside parallel (or whatever it may be). The code is pretty similar for the promise libraries so I'll leave that as an exercise to you!
Let me know that this helped.