Render data sent to Express post router - javascript

I'm starting with Express and I have a question; I have the setup and everything, I've made some simple things but know I want to interact with an API, to do what I want to do I need to the data that I want to get it's from an input field. I want to refresh the main (/) page with the data that was sent. Like a client-side ajax request. I don't know how to send the data that was sent to the post router to the get router without having to go to another link (i.e. localhost:3000/link), i want to stay in the same page where the request was done. I'm using pug (jade) in the template
Express:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', (req, res, next) => {
res.render('index');
});
/* POST HANDLER */
router.post('/link', function(req, res, next) {
console.log(req.body);
});
module.exports = router;
jQuery:
$('#shortLink').on('click', () => {
$.ajax({
type: 'POST',
url: '/link',
data: $('linkInput').val()
});
});
So, to be clear. User puts something on the input field; sends that data to the post router, I want to get the information sent to the post router to be sent to the get router without having to leave the page where the request was done. Let me know if I didn't explain myself very well.

Let's just say you have the body parser set up and understand how does the templating work.
In this what you want is to somehow save the data somewhere on the server. Now in a very simple case you can just save it to variable:
var data = null;
router.get('/', (req, res, next) => {
res.render('index', { data: null });
});
router.post('/link', function(req, res, next) {
data = req.body
res.send('');
});
Then in your template you can do p= data.
Now after you post to the /link then on the next refresh / will show the data.
In most web applications though, people will save these things to the database. Here's an example for MongoDB saving the data to specific document:
router.get('/', (req, res, next) => {
collection.findOne({ id: 'specificDoc'}, function (err, result) {
if (err) {
next(err);
return;
}
res.render('index', { data: result.data });
});
});
router.post('/link', function(req, res, next) {
collection.update({ id: 'specificDoc', { data: req.data }, { upsert: true }, function (err, result) {
if (err) {
next(err);
return;
}
res.send('');
});
});
Probably you might also start using sessions and save the data depending on the user using cookies or other methods. Here's a toturial for using sessions in express.

Related

Node.js send JSON to client

I am new to Node.js and javascript. I have a problem which I can't solve. I have a Node application, also I am using Express.
My problem: I have a script that sends a JSON to my server. This data is then stored in my MongoDB. What i want to do now is display that data on another page. This is what i have:
router.post('/', function(req, res, next) {
MongoClient.connect(url, function(err, db) {
var dbase = db.db("db");
dbase.collection('db').insertOne(req.body, function (err, result) {
if (err)
console.log('error');
else
console.log('success');
res.render('result');
});
});
});
What would be the best way to display the data stored in req.body? And could I send it to 'result'? Or should I display the data within the InsertOne-Function?
Please read the express documentation for all the details.
The JSON response can be sent using res.json() method.
Your code will look like this -
router.post('/', function(req, res, next) {
MongoClient.connect(url, function(err, db) {
var dbase = db.db("db");
dbase.collection('db').insertOne(req.body, function (err, result) {
if (err)
console.log('error');
else
res.json(result);
});
});
});

How can i store token value into my local javascript file

Hi am a beginner to Nodejs i have used passportjs token based authentication if the user logins it provides a token for each user i want to perform some operations based for the users who has token values for example if the user want to see the list of registered users they can view it if he has the token value. Now it provides me the token value perfectly in Postman but i don't know how to store it in a variable and call it via FRONT-END. I want do it via Front End(If he clicks the get users button) it should display the list of users.I have done that in POSTMAN it works finely i don't have an idea how to do it via frontend.
My user Code(Login/Logout)
var express = require('express');
var router = express.Router();
var User = require('../models/user');
var passport = require('passport');
var Verify = require('./verify');
/* GET users listing. */
router.route('/')
.get(Verify.verifyOrdinaryUser, function(req, res, next) {
User.find({}, function (err, users) {
if (err) throw err;
res.json(users);
});
});
router.post('/register', function(req, res, next) {
User.register(new User({ username : req.body.username }),req.body.password, function(err, user) {
if (err) {
return res.status(500).json({err: err});
}
user.save(function(err,user) {
passport.authenticate('local')(req, res, function () {
return res.status(200).json({status: 'Registration Successful!'});
});
});
});
});
router.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) {
return next(err);
}
if (!user) {
return res.status(401).json({
err: info
});
}
req.logIn(user, function(err) {
if (err) {
return res.status(500).json({
err: 'Could not log in user'
});
}
var token = Verify.getToken(user);
res.status(200).json({
status: 'Login successful!',
success: true,
token: token
});
});
})(req,res,next);
});
router.get('/logout', function(req, res) {
req.logout();
res.status(200).json({
status: 'Bye!'
});
});
module.exports = router;
Main.js File. In this main.js file i want to send that token in this get method any idea?
$(".get-users-button").click(function() {
$.ajax({
method: "GET",
url: " http://localhost:3000/users"
})
.done(function(msg) {
console.log(msg);
template(msg);
});
});
When you get back a successful response from the POST to your /login endpoint, store the token on client-side (e.g., window.localStorage.setItem('<your-namespace>-user-token', <the token goes here>);)
Then, when user clicks the 'get-users-button', get the token out of storage (e.g., window.localStorage.getItem('<your-namespace>-user-token'); and store it in a variable if you want.
Then, on your request to get users, add your { 'x-access-token': <token variable goes here> } to your request headers.
As per the documentation for Passport:
If authentication succeeds, the next handler will be invoked and the req.user property will be set to the authenticated user.
Now if I'm understanding your question correctly, you want to pass the token value you obtain from:
var token = Verify.getToken(user)
to the view in which your front-end can do something with. You can pass variables to the view using the following middleware:
app.use((req, res, next) => {
res.locals.token = Verify.getToken(req.user)
next()
}
See the documentation for res.locals for more details.
Example usage:
app.js
const express = require('express')
const app = express()
app.set('view engine', 'pug')
app.use((req, res, next) => {
res.locals.text = 'asdf'
res.locals.token = 'abc'
next()
})
app.get('/', (req, res) => {
res.render('index')
})
app.listen(3000, () => {
console.log('listening on 3000')
})
views/index.pug
doctype html
html
head
title= title
body
h1= text
script.
console.log('#{token}')

How to redirect to view page using mongoDB and node.js

I am new with node.js, mongoDB and jade.
To redirect to userlist page I have following route in /routes/index.js
router.get('/userlist', function(req, res) {
var db = req.db;
var collection = db.get('usercollection');
collection.find({},{},function(e,docs){
res.render('userlist', {
"userlist" : docs
});
});
});
This route redirects me to userlist page. There I display a list of all users. Here I have a link on each record to view details:
following is my userlist.jade
extends layout
block content
h1.
User List
ul
each user, i in userlist
li
a(href="/viewuser/id/#{user._id}")=user.username
This:
a(href="/viewuser/id/#{user._id}")=user.username
Gives me:
Dhara
Now I don't know what route should be there for view details on click of the link and how to get selected record data for view screen.
I use a clear and distributed stack MEAN.js, with a yeoman constructor that will help you to build secure and good-practice programming applications.
This is the way I get a concrete user data. It´s a little more spread than your code but it´s clear.
Hope it helps!
routes.js
app.use('/api/users', require('./api/user'));
api/user/index.js
var controller = require('./user.controller');
router.get('users/:id', controller.show);
user.controller.js:
// Get a single user
exports.show = function(req, res) {
User.findById(req.params.id, function (err, user) {
if(err) { return handleError(res, err); }
if(!user) { return res.send(404); }
return res.json(user);
});
};
then I´ll call for a user with an url like users/xxxxxx where xxxx is the user id. Then if you want to do it like /viewuser/id/xxxxxx you will need to change the route like this:
api/user/index.js
var controller = require('./user.controller');
router.get('viewuser/id/:id', controller.show);
user.controller.js:
// Get a single user
exports.show = function(req, res) {
User.findById(req.params.id, function (err, user) {
if(err) { return handleError(res, err); }
if(!user) { return res.send(404); }
return res.json(user);
});
};
maybe you need to specify the view in your app server file
app.get('/userlist', function(req, res){
res.render('userlist', {
title: 'Your_Title'
});
});
I hope to be helpful!

converting circular structure to json error on simple query

I have a very simple app that right now allows you to make an account, and just adds a document to a database. When I try to query the information and send it back using res.send() it errors and says converting circular structure to JSON. What does this mean? All of the objects in the document are strings. There's nothing fancy going on.
Here's the route it's erroring on:
var express = require('express');
var router = express.Router();
var cookieParser = require('cookie-parser');
/* GET users listing. */
router.get('/', function(req, res, next) {
// res.send(req.params);
});
router.post('/', function(req, res, next) {
console.log(req.body.nickname + " from the " + req.body.grade + " class registered.");
db.collection('users').insert({email: req.body.email, password: req.body.password, nickname: req.body.nickname, grade: req.body.grade}, function(err, result) {});
res.cookie("fss-sched-account", req.body.email);
res.cookie("fss-sched-password", req.body.password);
console.log(db.collection('users').find({}));
res.json(db.collection('users').find({}));
});
router.get('/nocookies', function(req, res, next) {
});
module.exports = router;
Here's a link to all of my code: Github
It means that you are trying to pass the "cursor" from the .find() rather than the "results". You likely just want:
db.collection('users').find({}).toArray(err,results) {
if (err) throw err; // or handle somehow
console.log(results);
res.json(results);
})
Where the .toArray() converts to an array as well as executing the query, returning a form of data you can actually use.

How to prevent entire user models from leaking up into the jade template

I am currently working on the log in portion of my project but I am working with express, passport-local and mongoose. I have a set of routes:
module.exports = function (app) {
app.get('/', function (req, res) {
res.render('index', { user : req.user, title : "Home" });
});
app.get('/register', function(req, res) {
res.render('register', { });
});
app.post('/register', function(req, res) {
Athlete.register(new Athlete({
username: req.param('username'),
firstName: req.param('firstName'),
lastName: req.param('lastName'),
dob: req.param('dob')
}), req.param('password'), function(err, athlete) {
if (err) {
console.log(err);
return res.render('register');
}
res.redirect('/');
});
});
app.get('/login', function(req, res) {
res.render('login', { user : req.user.username });
});
app.post('/login', passport.authenticate('local'), function(req, res) {
res.redirect('/');
});
app.get('/logout', function(req, res) {
req.session.destroy(function (err) {
res.redirect('/');
});
});};
I am currently able to sign in and sign out no problem and it displays my name as per the jade template using the p= user.firstName jade syntax. This though is burping up a object that contains a salt, hash, as well as the model values. This is clearly a huge security issue and I want to wrap my hear around what is going on between the route and the template. How can I prevent the entire user database object from coming up and which part of my code is causing the miscommunication.
First of all your user object won't leak as jade will be rendered on server side until you expose the secret information in your template. So passing extra information won't result in leaking.
Still if you want to restrict the entire user passing into jade, you can add a method in your user schema and call that method while using res.render.
userSchema.methods.getSafeUser = function() {
var user = this;
//filter user as per your requirements here.
return user;
}
Then in your controller, use
res.render('index', { user : req.user.getSafeUser() });

Categories