sending value from server to client node js - javascript

I am registering a user and after successful registration I want alert something in client side. So, what I do in server side, after registration I'm sending a value "registered" then when it gets that value, my client side would know that user is registred but I don't know how to get that value in my client side.
router.post('/registration', function (req, res, next) {
var stud = {
username: req.body.username,
email: req.body.email,
password: req.body.password,
admin: 0
};
mongo.connect(url, function (err, db) {
assert.equal(null, err);
db.collection('user-data').insertOne(stud, function (err, result) {
assert.equal(null, err);
console.log('Student inserted');
db.close();
res.json('registred');
})
})
});
My client side code
$('.MyForm').on('submit', function(event){
event.preventDefault();
$.ajax({
url: '/registration',
method: 'post',
success: function(response){
}
})
});
There is not very much because I don't know what to do next

All you still need to do is put the alert in the callback to the ajax request
success: function(response) {
alert('User registration succeeded!')
}

Since you're using HTTP protocol, why not use its cohesive response codes to indicate which action has happened? For example:
200 - user successfully created
400 - malformed input data
409 - one of unique user's model field has been already taken
And so on. Use method 'status' on response object to set appropriate return code. I assume that you are trying to create server with REST's rules in mind, therefore your endpoint should return freshly created entity on POST request.
mongo.connect(url, function (err, db) {
assert.equal(null, err);
db.collection('user-data').insertOne(stud, function (err, result) {
if(err) {
/* At this point, you may decide to check what error has been returned to decide which code will be returned*/
return res.status(400).json(err);
}
console.log('Student inserted');
db.close();
res.status(200).json(result);
})
})
On client side, code might be much more pleasant to eye after you would refactor it to use jQuery's ( since ver. 1.5.1 )'Promise API'
$.ajax({
url: 'http://localhost:8000',
method: 'POST'
})
.done(function( data ) {
})
.fail(function (reason) {
})

Related

How can I send one alert from my Node.JS to my Javascript client?

I'm doing a basic login from my node.js with mysql.
In my code example, if the session is correct send me to an html page called "home", but for this case, I need that once you make the session, my Javascript client sends an alert that says you have logged in or if its user is incorrect. And if it is correct, save the word "correct" in a variable that I can later use in my javascript file
How could I send that execution, so that my javascript file sends an alert?
app.post('/auth', function(request, response) {
var username = request.body.username;
var password = request.body.password;
if (username && password) {
connection.query('SELECT * FROM accounts WHERE username = ? AND password = ?',
[username, password], function(error, results, fields) {
if (results.length > 0) {
request.session.loggedin = true;
request.session.username = username;
response.redirect('/home'); //Here I want to change the instruction so that my javascript file sends an alert and create a varible that I can use in my file Javascript
} else {
console.log('Incorrect Username and/or Password!');
}
response.end();
});
});
Thanks
Here's a dirty trick you can use,but it will re-render the ejs view:
On server end(using express):
app.get('/route', function (req, res) {
res.render('view', { errormessage: 'your message' });
});
On client side(using ejs templates):
1.create an invisible div on your ejs template ,to access your ejs variable sent by server:
HTML:
<div id='status' class='invisible'><%= errormessage %></div>
CSS:
.invisible {
display: none;
visibility: hidden;
}
2.add this js script(jquery) at end of ejs to access this variable and create an alert:
<script>
if($('div#status').text()!='')
{
alert($('div#status').text());
}
</script>
At server side(Express middleware):
if(userNotExist) return res.status(401).end('Incorrect Username and/or Password!');
Handle at Client side.
Angular:-
$http().....
.error(function(data, status) {
console.error('Repos error', status, data);//"Repos error" 500 "User already exists."
});
jQuery:-
$.ajax({
type: "post",
url: url,
success: function (data, text) {
//success code here.
},
error: function (request, status, error) {
//error handling here.
}
});
There is no way to directly execute code on client side, by sending a directive from the server. What you want to do, is to send an information, and interpret it properly on the client.
For instance, you can use sessions
if (results.length > 0) {
request.session.loggedin = true;
request.session.username = username;
request.session.makeAlert = true;
response.redirect('/home');
}
In the /home route
app.get('/home', function(req, res){
const dataYouSend = {};
if (req.session.makeAlert) dataYouSend.makeAlert = true;
res.send(dataYouSend);
});
And finally in the JS code on /home route, use your data
fetch('adress/to/your/home')
.then(response => {
// It may not be precisely this, I don't know how you send data
if (response.makeAlert) alert("Alert!!!");
})
.catch(err => {
if(err) console.log(err);
});

Node js requests before render page

Recently I started learning node js and I have a question.
Before rendering a page I want to make 2 or more request to mongodb and then render page.
Currently I have sth like this:
exports.index = function(req, res) {
Manga.find({}, function(err, data){
if(err) console.log('error in getting some mangas');
res.render('index', {data: data, session: req.session.userId });
});
};
But I also want to get data of session user before rendering. How can I do that?
First you need to save data, about user, in to session object and then call:
res.render('index', {
data: data,
sessionID: req.session.userId,
email:req.session.emaill,
user_name: req.session.user_name
})
with express:
app.get("/",function(req,res,next){
Manga.find({}, function(err, data_from_db){
if(err) console.log('error in getting some mangas');
// set user data from DB in every request
req.session.user_data=data_from_db
next()
})
})//get
.......
.......
app.get("/index",function(req,res){
res.render('index', {
data: data,
sessionID: req.session.userId,
email:req.session.emaill,
user_name: req.session.user_name
})
})//index
Or you can use global functions and async filters from template engine to request directly user data if page need this data. https://mozilla.github.io/nunjucks/api#custom-filters

Issues with findOneAndUpdate

I am posting to the /update route.
This works because I can see my console.log() items printing in the terminal, see here:
However, my code seems to be totally ignoring the find one and update function.
All I want to do is run a put request to the route and have it update the post.
Here is my AJAX request:
$.ajax({
url: "/admin-panel/update/",
method: "PUT",
data: $data,
success: function(data, status) {
alert("Data: " + data + "\nStatus: " + status);
window.location.href = "/admin-panel/update/";
},
error: function(err) {
if (err) throw err;
}
});
And here is the put request handler in the backend:
router.put("/:action", function(req, res, next) {
if (req.params.action.toLowerCase() == "update") {
console.log("started")
var timelineItems = require("../schemas/timelineItems.js");
console.log("timeline items model inserted:", timelineItems)
timelineItems.findOneAndUpdate({_id: req.body.id}, function (err, post) {
if (err) {
next(err);
}
console.log("post:", post)
res.send("item updated!");
});
console.log("should be done");
} else {
var err = new Error('Access forbidden, please login!');
err.status = 403;
next(err);
}
});
I know that the right data is being run in the put request also as I checked the value of $data on the view and req.body on the backend too, so I am unsure why this isnt working.
your findOneAndUpdate query missing update parameter.
Model.findOneAndUpdate([conditions], [update], [options], [callback])
Check this doc

Send REST calls from Node server to third party application using OAuth

I'm implementing a server that handles chat messages. In some cases I want to access data from a JIRA instance. I'm using passport-atlassian-oauth strategy for authenticating with JIRA and BearerStrategy for requests, but my issue is that the authentication is only valid in the browser after a user has given "My Server" read and write access to JIRA. In many guides they just call res.redirect('/successfulLogin') or something similar after a successful authentication, but I would instead like to do a rest call to JIRA, process the data and send it to my connected client application.
How do I do that?
I'm completely new to all this and everything just spins around in my head. I save and have access to the token used for authentication and when I for instance navigate to .../test/access_token=?[token] in my browser it works.
passport.use(new BearerStrategy(
function(token, done) {
// Find user by token
client.smembers('access_token:' + token, function(err, replies) {
if (err) {
return done(err);
}
// if user found
// TODO: yet again, hard coded for one
if (replies.length > 0) {
console.log('SHOULD BE 1:', replies[0]);
client.hgetall('users:' + replies[0], function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false);
}
return done(null, user, {scope: 'all'});
});
}
});
}
));
As you can see it's hard coded for just one user and I'm using Redis as a "database".
passport.use(new AtlassianOAuthStrategy({
applicationURL: 'http://localhost:2990/jira',
callbackURL: '/auth/atlassian-oauth/callback',
consumerKey: RsaPublicKey,
consumerSecret: rsaPrivateKey,
clientId: 'MyBot'
},
function(accessToken, tokenSecret, profile, done) {
// Find user
client.hgetall('users:1', function(err, user) {
if(err) {
return done(err);
}
// user not found
if(!user) {
// create new user, no worries!
// TODO: HARD CODED FOR ONE USER
client.hmset('users:1', 'id', profile.id, 'access_token', accessToken, function(err, res) {
client.sadd('id:admin', '1');
client.sadd('access_token:'+ accessToken, '1');
client.hgetall(profile.id, function(err, user) {
return done(null, user);
});
});
} else {
// Update access token!
client.hmset(profile.id, 'access_token', accessToken, function() {
client.sadd('access_token:' + accessToken, '1', function() {
client.hgetall(profile.id, function(err, result) {
return done(null, user);
});
});
});
}
});
}
));
Here's the rest
app.get('/auth/atlassian-oauth',
passport.authenticate('atlassian-oauth', {session: false, scope: []}),
function(req, res) {
console.log('- Function: /auth/atlassian-oauth - should not be called)');
});
app.get('/auth/atlassian-oauth/callback',
passport.authenticate('atlassian-oauth', {session: false, failureRedirect: '/login'}),
function(req, res) {
console.log('- Function: /auth/atlassian-oauth/callback - Authentication successful!', req.user.access_token);
// Update access token!
// Should I even do this? Shouldn't I already have the correct token?
client.hmset('users:1', 'access_token', req.user.access_token, function() {
client.sadd('access_token:' + req.user.access_token, '1', function() {
client.hgetall('users:1', function(err, result) {
res.redirect('/test?access_token=' + req.user.access_token);
});
});
});
});
So now that you've seen some relevant (just tell me and I'll post more) code, how do I send a rest call to JIRA without getting a 401? :)
EDIT: Any help appreciated! You would make me really happy if you just can point me into the right direction!
Ok. I figured it out! First of all you want to save both you access token and token secret to you db in AtlassianOAuthStrategy. Second, in order to send a REST call to a third party service you can just use http request with OAuth:
var request = require('request');
var oauth = {
signature_method : 'RSA-SHA1',
consumer_key : RsaPublicKey,
private_key : rsaPrivateKey,
token : [get access_token from you db],
token_secret : [get token_secret from you db]'
};
var url = 'http://localhost:2990/jira/rest/api/2/issue/' + id;
request.get({url:url, oauth:oauth, json:true}, function (e, r, issue) {
console.log(issue)
});
Now that everything is working I'm going to start refactoring and reading some more documentation in order to make the design prettier and figure out how to use Redis properly :)

how to redirect using pure javascript in an express application

I have a node.js/express/mysql/angular.js application and I'm trying to redirect a user after they login, on the server side. This is the server-side controller and I cannot figure out how to redirect the user to another page. Ive tried res.render, res.redirect, window.location.href with no success. Errors I'm getting with res.render() are 'No default engine was specified and no extension was provided.' window.location.href says window is undefined. And res.redirect() allows me to console.log the html of the page I want to direct too. Any help is greatly appreciated, Thanks!
var Query = require('./../models/query.js');
module.exports = (function(){
return {
show: function(req,res) {
req.getConnection(function(err,connection){
connection.query('SELECT * FROM users',function(err,rows){
res.json(rows);
});
});
},
add: function(req,res){
var newUser = {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: req.body.password,
created_at: req.body.created_at
};
var table = "users";
Query.insert(req,newUser,table,function(err,results){
if(err) return res.json(err);
Query.find(req,table,function(err,results){
if(err) return res.json(err);
res.json(results);
});
});
},
login: function(req,res) {
var input = req.body;
console.log("got here", input);
req.getConnection(function(req, connection) {
// console.log("got connections",connection);
connection.query('SELECT * FROM users WHERE email = ?',input.email, function(err, rows) {
if (err) {
console.log("User doesn't exist: %s", err);
res.redirect('/', { data:"failed"});
} else {
if (input.password == rows[0].password) {
console.log("User password is matched");
*** success redirect right here ****
res.redirect('/static/taxonomer'+'.html');
} else {
console.log("failed here", rows[0].password);
res.redirect( '/', { data:"failed"});
}
}
});
});
}
};
})();
Without seeing your routes I am guessing that login method on the above controller corresponds to a POST route. For example,
app.post('some/login/route', theAboveController.login)
Therefore, the redirect is controlled on the client side.
So, make then following changes:
1) Use res.send to send a redirect url as a string to the client. For example,
res.send('/static/taxonomer'+'.html')
2) Then on the client side in your success callback, change the location to the url you received from the res.send method. For example,
$http.post('/some/login/route', data).then(function(response) {
$window.location.href = response;
}, errorCallback);
Express's docs are pretty good here: http://expressjs.com/api.html#res.redirect
res.redirect('https://stackoverflow.com'); will redirect them to that specific URL.
res.redirect('/foo'); will redirect to a specific URL
res.redirect('back'); will redirect to the referrer. So you can do something like a middleware that redirects to /login and then the login finishes successfully and it goes back to the original path.

Categories

Resources