I need help on this one I'm stuck for three days... I need to deploy a node.js web app with MySql database to Heroku. Here what I`m done so far:
I succeeded to connect to heroku local on port 5000;
I succeeded to connect with the command heroku run node app.js;
I insert a proc file on the root directory :
Please help!
web: node app.js
But when I open the app from the heroku web site I have the following errors:
Here is my server file :
const express = require("express");
const exphbs = require("express-handlebars");
const bodyParser = require('body-parser');
const mysql = require('mysql');
require("dotenv").config();
const app = express();
const port = process.env.PORT || 5000;
// Parsing middleware
// Parse application/x-www-form-urlcoded
app.use(express.urlencoded({extended: true})); //New
app.use(express.json()); //To parse the incoming requests with JSON payloads
//to load static file
app.use(express.static("public"));
//Templating engine to change the extenion of file from .handlebar to .hbs
app.engine("hbs", exphbs({extname:".hbs"}));
app.set("view engine","hbs");
//Routes
const routes = require('./server/routes/user');
app.use("/",routes);
//Listen on port 5000
app.listen(port, () => console.log(`Listening on port ${port}`));
Here my app.js file
const mysql = require('mysql');
//Connection pool
let connection = mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME
});
// View Users
exports.view = (req, res) => {
//User the connection
connection.query('SELECT * FROM user WHERE status="active"', (err, rows) => {
//when done with the connection, release it
if (!err) {
let removedUser = req.query.removed;
res.render('home', { rows, removedUser });
} else {
console.log(err);
}
console.log('The data from user table:\n', rows);
});
};
//find user by Search
exports.find = (req, res) => {
let searchTerm = req.body.search;
//User the connection
connection.query('SELECT * FROM user WHERE first_name LIKE ? OR last_name LIKE ?', ['%' + searchTerm + '%', '%' + searchTerm + '%'], (err, rows) => {
if (!err) {
res.render('home', { rows });
} else {
console.log(err);
}
console.log('The data from user table:\n', rows);
});
};
exports.form = (req, res) => {
res.render('add-crew');
}
exports.create = (req, res) => {
const { first_name, last_name, email, phone, coc, expiration, PSSR, FFB, ADV } = req.body;
let searchTerm = req.body.search;
//User the connection
connection.query('INSERT INTO user SET first_name = ?,last_name = ?,email = ?,phone = ?,coc=?,expiration=?,PSSR=?,FFB=?,ADV=?', [first_name, last_name, email, phone, coc, expiration, PSSR, FFB, ADV], (err, rows) => {
if (!err) {
res.render('add-crew', { alert: 'Crew member added succesfully!' });
} else {
console.log(err);
}
console.log('The data from user table:\n', rows);
});
};
// edit crew function
exports.edit = (req, res) => {
//User the connection
connection.query('SELECT * FROM user WHERE id = ?', [req.params.id], (err, rows) => {
if (!err) {
res.render('edit-crew', { rows });
} else {
console.log(err);
}
console.log('The data from uer table:\n', rows);
});
}
// Update crew
exports.update = (req, res) => {
const { first_name, last_name, email, phone, coc, expiration, PSSR, FFB, ADV } = req.body;
connection.query('UPDATE user SET first_name=? ,last_name=?, email=?, phone=?, coc=?, expiration=?, PSSR=?, FFB=?, ADV=? WHERE id = ?', [first_name, last_name, email, phone, coc, expiration, PSSR, FFB, ADV, req.params.id], (err, rows) => {
if (!err) {
connection.query('SELECT * FROM user WHERE id = ?', [req.params.id], (err, rows) => {
//when done with the connection release it
// connection.release();
if (!err) {
res.render('edit-crew', { rows, alert: `${first_name} has been updated.` });
} else {
console.log(err);
}
console.log('The data from user table:\n', rows);
});
} else {
console.log(err);
}
console.log('The data from user table:\n', rows);
});
}
//delete crew
exports.delete = (req, res) => {
// User the connection
connection.query('DELETE FROM user WHERE id = ?', [req.params.id], (err, rows) => {
if(!err) {
let removedUser = encodeURIComponent();
res.redirect('/?removed='+ removedUser);
} else {
console.log(err);
}
console.log('The data from user table: \n', rows);
});
}
// hide user
// connection.query('UPDATE user SET status = ? WHERE id = ?', ['removed', req.params.id], (err, rows) => {
// if (!err) {
// let removedUser = encodeURIComponent('User successeflly removed.');
// res.redirect('/?removed=' + removedUser);
// } else {
// console.log(err);
// }
// console.log('The data from beer table are: \n', rows);
// });
// }
exports.viewall = (req, res) => {
//User the connection
connection.query('SELECT * FROM user WHERE id=?',[req.params.id], (err, rows) => {
//when done with the connection, release it
if (!err) {
res.render('view-crew', { rows });
} else {
console.log(err);
}
console.log('The data from user table:\n', rows);
});
}
Here my package.json file:
{
"name": "nodejs-usermanagement",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node app.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"express-handlebars": "^5.3.2",
"mysql": "^2.18.1"
},
"devDependencies": {
"nodemon": "^2.0.7"
}
}
Here an update about the errors that are coming out after 10 minutes:
Related
Below is the code snippet of a system which is asking email and password to Login into the system. The below code is always showing error that "email or password is incorrect" even if they are correct. I am using NodeJS and MySQL database, Please help!
exports.afterLogin = async (req, res) => {
try {
const { email, password } = req.body;
db.query('Select * FROM patient WHERE email= ?', [email], async (error, results) => {
const verified = bcrypt.compareSync(password,results[0].password);
if(error){
console.log(error);
}
//console.log(results);
else if (!results || !verified) {
res.status(400).render('patientLogin', {
message: 'Email or password is incorrect!',
messageClass:'alert-warning'
});
}
else {
//creating session
db.query('select * from patient where email=?',[email],(err,result)=>{
if(err)
{
console.log(err);
}else{
sess=req.session;
sess.patient={};
sess.patient.city=result[0].city;
sess.patient.name=result[0].first_name;
sess.patient.ids=result[0].patient_id;
// console.log(sess.patient);
patientSess=Object.assign(sess.patient);
// console.log(patientSess);
}
});
const id = results[0].id;
const token = jwt.sign({ id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRES_IN
});
console.log("Token is: " + token);
const cookieOptions = {
expires: new Date(
Date.now() + process.env.JWT_COOKIE_EXPIRES * 24 * 60 * 60 * 1000
),
httpOnly: true
}
res.cookie('jwt', token, cookieOptions);
res.status(200).redirect("/searchDoctor");
}
})
} catch (error) {
console.log(error);
}
}
I can't get all users, but if write manually it works.
class User {
static getAll(result) {
let sql = `SELECT * FROM users`;
sql.query(sql, (err, res) => {
if (err) {
console.log("error: ", err);
result(null, err);
return;
}
console.log("users: ", res);
result(null, res);
});
}
}
exports.findAll = (req, res) => {
User.getAll = (err, data) => {
if (err) return res.status(500).send({ message: err.message || "Some error occurred while retrieving users." });
res.send(data);
}
}
query() is a method of a mysql connection, you are using it as a string method:
let sql = 'SELECT * FROM users';
sql.query()
You should first create the connection with your database, and then use that connection object to make your queries, something like this:
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
con.connect(function(err) {
if (err) throw err;
con.query("SELECT * FROM users", function (err, result, fields) {
if (err) throw err;
console.log(result);
});
});
I have tried it through MongoDB, but I can't to use JOIN Query in mongoDB and my project is wide enough. So, Want to Create Restful API in node js in MySQL.
Can anyone suggest the solution
For creating REST API you can go with express JS
var express = require('express');
var app = express();
app.get('/', function (req, res) {
//BELOW-CODE
});
You can connect Mysql by following this code:
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
con.connect(function(err) {
if (err) throw err;
con.query("SELECT * FROM customers", function (err, result, fields) {
if (err) throw err;
console.log(result);
);
});
Note: Install expressJS framework to get started
Happy coding :-)
For MySQL with NodeJS you can use Sequelize, it's an ORM kinda like doctrine in symfony
http://docs.sequelizejs.com/
`'user strict';
var sql = require('./db.js');
//Task object constructor
var Task = function(task){
this.task = task.task;
this.status = task.status;
this.created_at = new Date();
};
Task.createTask = function createUser(newTask, result) {
sql.query("INSERT INTO tasks set ?", newTask, function (err, res) {
if(err) {
console.log("error: ", err);
result(err, null);
}
else{
console.log(res.insertId);
result(null, res.insertId);
}
});
};
Task.getTaskById = function createUser(taskId, result) {
sql.query("Select task from tasks where id = ? ", taskId, function (err, res) {
if(err) {
console.log("error: ", err);
result(err, null);
}
else{
result(null, res);
}
});
};
Task.getAllTask = function getAllTask(result) {
sql.query("Select * from tasks", function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else{
console.log('tasks : ', res);
result(null, res);
}
});
};
Task.updateById = function(id, task, result){
sql.query("UPDATE tasks SET task = ? WHERE id = ?", [task.task, id], function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else{
result(null, res);
}
});
};
Task.remove = function(id, result){
sql.query("DELETE FROM tasks WHERE id = ?", [id], function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else{
result(null, res);
}
});
};
module.exports= Task;
The home route for the initial request is "http://localhost:5000/contacts". After deploying to heroku, the UI is rendered but the data is not and I'm getting a status of 404: not found. The url shown is this one: "https://powerful-gorge-20271.herokuapp.com/contacts". I am using the Clear-DB add on on heroku as my mySql database. I have tried modifying the proxy in the react app's package.json file from "http://localhost:5000" to the heroku url but that does not work. The repo for this app is: https://github.com/aosante/React-Contact-Manager
I used this article https://daveceddia.com/deploy-react-express-app-heroku/ for guidance but it still doesn't work
This is the code in the app.js file
const express = require('express');
const cors = require('cors');
const mysql = require('mysql');
const path = require('path');
const port = process.env.PORT || 4000;
const app = express();
//Static file declaration
app.use(express.static(path.join(__dirname, 'client/build')));
//production mode
if (process.env.NODE_ENV === 'production') {
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('*', (req, res) => {
res.sendfile(path.join((__dirname, 'client/build', 'index.html')));
});
}
app.use(cors());
const SELECT_ALL_CONTACTS = `SELECT * FROM contacts ORDER BY firstName ASC`;
//Connection creation to mysql database
const connection = mysql.createConnection({
host: 'host goes here',
user: 'user goes here',
port: 'goes here',
password: 'password goes here',
database: 'heroku_cdf7d751774d818',
insecureAuth: true
});
connection.connect(err => {
if (err) console.log(err);
});
//Server start
app.listen(port, () => {
console.log('Server started on port ' + port);
});
app.get('/api', (req, res) => {
connection.query(SELECT_ALL_CONTACTS, (err, results) => {
if (err) {
res.send(err);
} else {
return res.json({
data: results
});
}
});
});
app.get('/api/contacts', (req, res) => {
connection.query(SELECT_ALL_CONTACTS, (err, results) => {
if (err) {
res.send(err);
} else {
return res.json({
data: results
});
}
});
});
app.post('/api/contacts/add', (req, res) => {
const { firstName, lastName, email, phone } = req.query;
const INSERT_CONTACT = `INSERT INTO contacts (firstName, lastName, email, phone) VALUES ('${firstName}', '${lastName}', '${email}', '${phone}')`;
connection.query(INSERT_CONTACT, (err, results) => {
if (err) {
console.log(err);
} else {
return res.send(results);
}
});
});
app.delete('/api/contacts/delete/:id', (req, res) => {
const { id } = req.params;
const DELETE_CONTACT = `DELETE FROM contacts WHERE id = ${id}`;
connection.query(DELETE_CONTACT, (err, results) => {
if (err) {
console.log(err);
} else {
return res.send(results);
}
});
});
app.get('/api/contacts/edit/:id', (req, res) => {
const { id } = req.params;
const GET_CONTACT = `SELECT * FROM contacts WHERE id = ${id}`;
connection.query(GET_CONTACT, (err, results) => {
if (err) {
res.send(err);
} else {
return res.json({
data: results
});
}
});
});
app.put('/api/contacts/update/:id', (req, res) => {
const { id } = req.params;
const { firstName, lastName, email, phone } = req.query;
const UPDATE_CONTACT = `UPDATE contacts SET firstName = '${firstName}', lastName = '${lastName}', email = '${email}', phone = '${phone}' WHERE id = ${id}`;
connection.query(UPDATE_CONTACT, (err, results) => {
if (err) {
console.log(err);
} else {
res.send(results);
}
});
});
//production mode
if (process.env.NODE_ENV === 'production') {
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('*', (req, res) => {
res.sendFile(path.join((__dirname, 'client/build', 'index.html')));
});
}
//this goes in the end after all the requests
//build mode
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/client/public/index.html'));
});
And this is what's in the package.json file:
{
"name": "react-contact-manager",
"version": "1.0.0",
"description": "Simple contact manager with mysql backend",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon app.js",
"client-install": "npm install --prefix client",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"heroku-postbuild": "npm install --prefix client && npm run build - -prefix client"
},
"keywords": [
"react",
"mysql"
],
"author": "Andrés Osante",
"license": "ISC",
"dependencies": {
"concurrently": "^4.1.0",
"cors": "^2.8.5",
"express": "^4.16.4",
"mysql": "^2.16.0",
"nodemon": "^1.18.9"
}
}
I also added a Procfile with "web:node app.js" written on it but that didn't help
A couple of things. The ordering of routes is important in Express--It's first come, first serve.
Since in production, you capture all your routes app.get('*', to serve your front-end, the other routes can never be hit. You need to move this toward the end of app.js after declaring your other routes.
Also, you should carefully define your routes so that there is no collision between the front and back end. I'm not sure if you are using React Router or not, but you define a get route on the root of your application ('/'). This will conflict with your front-end. This seems to be doing the same thing as /contacts, so go ahead and remove the root definition.
I'm not sure, personally, perhaps someone else can add, but in package.json in your scripts, consider redefining heroku-postbuild. I'm not sure what changing the directory might do to the app, maybe nothing. But here is another way of handling this:
"heroku-postbuild": "npm install --prefix client && npm run build --prefix client"
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.