Connect MySQL to Fullcalendar - mysql

Good day everyone.
I try to feed resources from MySQL db to FullCalendar app. The example in its official docs uses PHP script and effectively all examples I found here also utilize PHP. I just started learning web development and haven't touched PHP and wonder if it's possible to tell the calendar to fetch data from db using node.js and EJS. Here's what I've accomplished so far (please be empathic and forbearing with my mistakes):
In app.js file I put a connection to MySQL, then in GET route it queries data from db and converts it to JSON object (resources).
app.js renders scheduler.ejs and I assume that JSON data is stored in resourcesFeed.
app.js
var express = require('express'),
app = express(),
PORT = process.env.PORT || 3000,
bodyParser = require('body-parser'),
mysql = require('mysql');
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/node_modules'));
app.use(bodyParser.urlencoded({extended: true}));
app.set('view engine', 'ejs');
// create connector to DB
var con = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'gdp_scheduler'
});
// connect to DB
con.connect(function(err) {
if (err) throw err;
console.log('Connection to DB established')
});
app.get('/scheduler', function(req,res){
// query the DB
con.query('SELECT id, given_name, level, color FROM resources',
function (err, getResources) {
if (err) throw err;
// convert to JSON
resources = JSON.parse(JSON.stringify(getResources));
console.log(resources);
return resources;
});
// render scheduler page
res.render('scheduler', {resourcesFeed: resources});
});
app.listen(PORT, () => {
console.log('Server is up on port:' ,PORT);
});
scheduler.ejs
<%- include("partials/header") %>
<div class="container-fluid">
<!-- Header -->
<div>
<h1>GDP Projects Timeline</h1>
</div>
<div>
<div id='calendar'></div>
</div>
</div>
<%- include("partials/footer") %>
The scheduler.ejs header has a link to scheduleSetup.js file.
In scheduleSetup.js file, I try to make the calendar to fetch resources from resourcesFeed. And it doesn't work.
scheduleSetup.js
document.addEventListener('DOMContentLoaded', function() {
//Initialize calendar
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source', //hide lices=nc=se warning
plugins: [ 'resourceTimeline', 'bootstrap', 'interaction' ], //connect plugins to page
defaultView: 'resourceTimelineMonth', //define timeline view
editable: true, //enable draggable events
droppable: true, //it allows things to be dropped onto the container
resourceGroupField: 'level', //grouping
resources:
'resourcesFeed',
// [
// { id: 2, title: 'John', level: 'Personnel', color: null },
// { id: 3, title: 'TEST', level: 'Projects', color: 'red' }
// ],
resourcesInitiallyExpanded: true, //the way how resources show up
events: {
url: '/sources/events.json',
}, //link to event json file
defaultTimedEventDuration: '24:00', //deafult event duration
weekNumberCalculation: 'ISO', //first day of week Monday
resourceAreaWidth: '10%', //resource column width
resourceLabelText: 'Projects/Personnel', //resource label
//header layout
header: {
left: 'promptProject today prev,next',
center: 'title',
right: 'resourceTimelineMonth, resourceTimelineYear,'
},
//footer
footer: true,
footer: {
left: 'promptPersonnel'
},
height: 'auto', //calendar window size (including header and ffoter)
//text on standard buttons
buttonText: {
today: 'Today',
month: 'Month',
year: 'Year'
},
//create custom buttns
customButtons: {
promptProject: {
text: 'Add project',
click: function() {
var title = prompt('Project name');
if (title) {
calendar.addResource({
title: title,
level: "Projects"
});
}
}
},
promptPersonnel: {
text: 'Add personnel',
click: function() {
var name = prompt('Name');
if (name) {
calendar.addResource({
title: name,
level: "Personnel"
});
}
}
}
}
});
calendar.render();
});
I try to comprehend the general sequence of how data is transmitted back and forth between backend and client-side, and what methods are used for this, however apparently have no clear picture yet. Any suggestions, tips, and help would be very much appreciated.
Thank you

Related

What am I missing? I want to store my session to MySQL database

I have my database up and running. The connection is working. I want to store my session in to the database.
Here's my code. When I run the server on my browser I get this error:
RequestError: No connection is specified for that request.
I just kept it simple in one app.js file.
var express = require('express');
var mysql = require('mysql2');
var session = require('express-session');
var MsSQLStore = require('mssql-session-store')(session);
var port = 3000;
var app = express();
var connection = mysql.createConnection ({
host: 'localhost',
user: 'root',
password: '.....',
database: 'node'
});
var sess = {
secret: 'Pearl',
resave: false,
saveUninitialized: true,
store: new MsSQLStore(options)
};
var options = {
connection: connection,
ttl: 3600,
reapInterval: 3600,
reapCallback: function() {console.log('expired sessions were removed');}
};
if(app.get('env') === 'production') {
app.set('trust proxy', 1)
sess.cookie.secure = true
}
app.use(session(sess));
connection.connect();
connection.query('Select 1 + 1 AS solution', (err, rows, fields) => {
if (err) throw err
console.log('the solution is: ', rows[0].solution)
});
app.listen(port, (req, res) => {
console.log('the server is running, ' + ' please, open your browser at http://localhost:%s', port);
});
app.get('/', (req, res) => {
res.end('Hello World');
});
In store: new MsSQLStore(options), you are attempting to use options before you've assigned it a value so it will be undefined when you try to use it. Move the definition and assignment of options to BEFORE you use it.
So, change this:
var sess = {
secret: 'Pearl',
resave: false,
saveUninitialized: true,
store: new MsSQLStore(options)
};
var options = {
connection: connection,
ttl: 3600,
reapInterval: 3600,
reapCallback: function() {console.log('expired sessions were removed');}
};
to this:
const options = {
connection: connection,
ttl: 3600,
reapInterval: 3600,
reapCallback: function() {console.log('expired sessions were removed');}
};
const sess = {
secret: 'Pearl',
resave: false,
saveUninitialized: true,
store: new MsSQLStore(options)
};
Incidentially, if you use let or const for these, then this would have been flagged by the interpreter as an error which is yet another reason to stop using var entirely.

Got connect ECONNREFUSED node

I develop with mates for school a nodejs website. But I have this problem when I npm start.
I have been looking for few times a solution but find anything working for us.
Here is the error we get:
read: [Function],
secret: undefined,
cookies: { 'jenkins-timestamper-offset': '-7200000' },
signedCookies: {},
route:
{ path: '/question',
stack: [ [Object], [Object], [Object] ],
methods: { post: true, put: true, delete: true } } }
connect ECONNREFUSED
I just pick the last few lines because there are too many to copy/paste.
Here is my index.js file:
var express = require('express');
var mysql = require("mysql");
var md5 = require('MD5');
var router = express.Router();
var app=express();
var bodyParser = require("body-parser");
var questionList = [];
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
router.get("/ListQuestion",function (req,res){
client.query('SELECT * from question',function (err,results) {
res.render('ListQuestion', {listeQuestion: results});
})
});
/* GET home page. */
router.get('/', function(req, res) {
res.status(200).render('index', { title: 'Web-Service' });
});
router.get('/answer/:URI', function(req, res) {
var client=mysql.createConnection({
host : '172.17.0.2',
user : 'root',
password : 'rootroot',
database : 'questionreponse'
});
client.query('SELECT * from question WHERE answer !="NULL" AND uri= "'+req.params.URI+'" GROUP BY answer ORDER BY answer DESC' , function (error, results) {
console.log(results);
if (results && results[0] && results[0].answer && results[0].answer!=''){
res.status(200).render('answer', {answer: results[0].answer});
console.log(results[0].answer);
}else{
Same as before I cant copy the whole file because too long, if you need specific lines you can ask for.
If you have any solution to make it work I will take it.
Thanks in advance. :)

how to update user table in node js

mycode is--
updateUser: function(req, res) {
var data = req.body;
var option = {
name: data.name,
mobile: data.mobile,
domain: data.domain,
}
userModel.update(option, function (error, rows) {
console.log('###############',error || rows);
if(!res){
//TODO: Error handling
console.log("ERROR", res);
res.status(200).send({"status_code": 0, 'message': 'Some error occured'});
return;
}
res.status(200).send({"status_code": 1, 'message': 'Succesfully Updated'});
})
},
the problem is updated all user coloumn.
in the code how to give id of the particular update data.
If you are not writing some very low level driver, I would recommend to use ORM like https://github.com/sequelize/sequelize. The very first example on their homepage shows:
var Sequelize = require('sequelize');
var sequelize = new Sequelize('database', 'username', 'password');
var User = sequelize.define('user', {
username: Sequelize.STRING,
birthday: Sequelize.DATE
});
sequelize.sync().then(function() {
return User.create({
username: 'janedoe',
birthday: new Date(1980, 6, 20)
});
}).then(function(jane) {
console.log(jane.get());
jane.update({
username: 'a very different username now'
}).then(function() {
console.log(jane.get());
})
});
You should use Bookshelf.js, good ORM, easy to use

Node.js MySQL model designing

I'm developing a node.js application using MySQL database but I'm stuck with making models on the node.js side of my application. I've used Mongoose before to produce schemas and use models to do database functions but i couldn't find such support for MySQL. Can anyone suggest a proper way to isolate my database functions in node.js like I could do with Mongoose. here's my app.js and users model i'm using right now.
app.js
var express= require("express");
var bodyParser = require("body-parser");
var mysql = require("mysql");
var UserModel= require("./models/User.js")
var app=express();
var sql = mysql.createConnection({
host: "localhost",
user: "root",
password: "1234",
database: "dricm"
});
sql.connect(function (err) {
if(err){
console.log("error");
}else{
console.log("connected");
}
});
app.set("views", "./views");
app.use(express.static("node_modules/bootstrap/dist"));
app.use(express.static("public"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.get('/', function (req, res) {
res.render("signup.jade");
});
app.post('/signup', function (req, res) {
var obj= {
username: req.body.username,
password: req.body.password
};
UserModel.createUser(obj);
res.redirect("/");
});
app.listen(3000, function () {
console.log("server running at 3000");
});
User.js (probable model)
var mysql= require("mysql");
var bcrypt = require("bcryptjs");
var sql = mysql.createConnection({
host: "localhost",
user: "root",
password: "1234",
database: "dricm"
});
sql.connect(function (err) {
if(err){
console.log("error");
}else{
console.log("connected");
}
});
var User= {
}
User.createUser = function createUser(newUser) {
bcrypt.genSalt(10, function(err, salt){
bcrypt.hash(newUser.password,salt, function (err, hash) {
newUser.password = hash;
var query = sql.query("INSERT INTO USERS set ?", newUser, function (err, res) {
console.log(query);
if(err) {
console.log("error");
}
else{
console.log(res.insertId);
}
});
});
});
}
module.exports= User;
What you are looking for is called an ORM (Object-relational mapping) Mongoose is one for MongoDB (Which is a NOSQL document oriented database)
There are other ORMs for relational databases that work with Node.js, The most popular right now is Sequelize which I have personally used and recommend.
With Sequelize you can put your models in different files just like Mongoose however in order to load them on, you need to add them with a simple script inside your index.js
Imagine the following Workspace:
--models/
----User.js
----Permissions.js
--index.js
And your model definitions should be something like this:
User.js
const UserModel = (sequelize, Sequelize) => {
const {INTEGER, STRING, FLOAT, BOOLEAN, DATE} = Sequelize
const User = sequelize.define('User', {
UserId: {type: INTEGER, primaryKey: true, autoIncrement: true},
Username: {type: STRING, primaryKey: true, allowNull: false},
Password: STRING
})
return User
}
module.exports = UserModel
Permissions.js
const PermissionsModel = (sequelize, Sequelize) => {
const {INTEGER, STRING, FLOAT, BOOLEAN, DATE} = Sequelize
const Permissions = sequelize.define('Permissions', {
Role: {type: STRING, allowNull: false},
ControllerAddress: {type: STRING, allowNull: false}
})
return Permissions
}
module.exports = PermissionsModel
Now you need to use the following script to use them inside your index.js
let normalizedPath = require('path').join(__dirname, "models")
require('fs').readdirSync(normalizedPath).forEach((file) => {
sequelize.import('./models/' + file)
})
let {User, Permissions} = sequelize.models
Now you can use the User and Permissions instances to control them and call functions like:
User.create({Username, Password})

Setting Stormpath Configuration Options

I am trying to customize the registration page with Stormpath and I can't figure out why the configuration options are not working. The enableXXX and requireXXX work, but none of the info inside web:{...} is showing up. I've tried reordering the options, but that doesn't work either.
Specifically, I want to:
-- Register users at /signup instead of /register. Right now only /register is working.
-- I want to redirect them to another site after registration. I randomly put google.com in there, but I'm still redirected to "/" after registration is complete.
-- I want to reorder the registration fields. I want email to be the first field, but username is currently first.
Here's app.js:
// Import required modules.
var express = require('express');
var stormpath = require('express-stormpath');
var path = require('path');
var engine = require('ejs-mate');
var app = express();
// use ejs-locals for all ejs templates:
app.engine('ejs', engine);
// Configure public views
app.set('views','./views');
app.use(stormpath.init(app, {
apiKeyFile: process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'] + ~removed
secretKey: '~removed',
application: '~removed',
enableRegistration: true,
enableGivenName: false,
requireGivenName: false,
enableSurname: false,
requireSurname: false,
website: true,
api: true,
web: {
register: {
uri: '/signup', // Use a different URL
nextUri: 'http://google.com', // Where to send the user to, if auto login is enabled
fields: {
passwordConfirm: {
enabled: true,
required: true
}
},
fieldOrder: [ "email", "username", "password", "passwordConfirm" ],
}
},
enableUsername: true,
requireUsername: true,
enableConfirmPassword: true,
requireConfirmPassword: true
}
));
app.get('/', function(req, res) {
res.render('home.ejs', {
title: 'Welcome'
});
});
app.get('/', function(req, res) {
res.send('home page!');
});
app.listen(process.env.PORT || 3000);
Other possibly relevant info:
-- The site is hosted on Heroku, but I'm not using the Stormpath add-on because I couldn't get it to work.
-- I'm on a Mac.
I've been stuck on this for days and I haven't been able to figure out what I'm doing wrong. Any help would be much appreciated.
The issue is likely this: we released a new version of this library recently which has new configuration options, and it appears you are using our OLD docs as a reference.
Here's what you'll want to do:
Update to the latest express-stormpath release. Then use the code below: (I converted your example to work with the latest release):
app.use(stormpath.init(app, {
client: {
apiKey: {
file: process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'] + '~removed'
}
},
application: {
href: '~removed',
},
web: {
register: {
enabled: true,
uri: '/signup',
nextUri: 'http://google.com', // don't send them here =)
fields: {
username: {
enabled: true,
required: true
},
givenName: {
enabled: false,
required: false
},
surname: {
enabled: false,
required: false
},
passwordConfirm: {
enabled: true,
required: true
}
},
fieldOrder: ['username', 'email', 'password', 'passwordConfirm']
}
},
website: true,
api: true
}));