How to message client when afterCreate database hook process is ready? - javascript

I have an express with sequelize (using postgres) REST backend server. When I post a create request from my client the database entry is created then a afterCreate hook is running a processing script for a second or so. This is running fine using the afterCreate hook form sequelize.
Subsequently I need to let the client know the processing is ready, upon which the client will run some process of its own. How do I message to the client?

I'm not a Node expert and my answer might be wrong, but based on the https://groundberry.github.io/development/2016/11/06/continue-building-your-node-app-with-express-and-sequelize.html couldn't you do the following:
router.post('/', function(req, res) {
//node return reply after running the create
return models.User.create({ username: req.body.username }).then(function() {
return res.json({ message: 'New user created' });
});
});

Related

How do I pass the user's server side request to the client side?

I don't know if I phrased the title correctly, so sorry if it confused you.
I have two servers running (using different ports), one is my client side running on React, and the other one is my server side running on Express.
I'm trying to have the user log in via Steam, so I'm using the passport-steam library. Basically, when the user logs in on steam, it passes the user data to the server-side req session, but I need it to be on the client-side so it can access the data and load it on the website.
Here's some code if that helps
// /routes/auth.js
// /AUTH ROUTER
// GET Request the CLIENT will send to get their info
router.get("/user", ensureAuthenticated, function (req, res) {
res.json(req.session.user);
// returns undefined because their session is saved on the server side
});
// GET Requests used to sign in and authenticate
router.get("/steam", passport.authenticate("steam", { failureRedirect: "http://localhost:3000/login" }), function (req, res) {
res.redirect("http://localhost:3000");
});
router.get("/steam/return", passport.authenticate("steam", { failureRedirect: "http://localhost:3000/login" }), async function (req, res) {
res.redirect("http://localhost:3000");
});

Express JS/ MongoDB Post not working

I started working on a MERN App today and am trying to write a restful api. First I am using mlab to store my mongodb database. I have succesfully connected to this database after creating a user. I can manually create a collection and inject some data into this collection. From my server.js file I can then get the data stored in here.
MongoClient.connect(db_url, (err, database) => {
if (err) return console.log(err);
var collection = database.collection('memories'); // Collection called memories
app.listen(3000, () => {
console.log("Listening on 3000");
});
});
Thats all fine and dandy but I want to take it to the next level. I want to write a CRUD api for the collection Memory. Coming from django, I would like to create my model first. Therefore, in my models/memory.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var MemorySchema = new Schema({
name: String,
description: String
});
module.exports = mongoose.model('Memory', MemorySchema);
Then I went ahead and started working on my routes/api/api.js:
let router = require('express').Router();
let Memory = require('../../../models/memories');
router.use(function (req, res, next) {
console.log("Something is happening");
next(); // Request stops at middleware without next()
});
router.route('/memory')
.post(function (req, res) {
let memory = new Memory();
memory.name = req.body.name;
memory.description = req.body.description;
memory.save(function (err) {
if (err) {
res.send(err);
}
res.json({message: 'Memory Created'});
});
})
.get(function (req, res) {
res.json({message: 'First memory'});
});
module.exports = router;
And in my server.js I call this module:
const apiRoutes = require('./routes/api/api');
app.use('/api/', apiRoutes);
However, after testing the post api with postman, it the POST request just takes forever before showing up as Could not get any response. However, the GET request works. What am I missing?
EDIT: So the post function is having trouble saving the model instance...
Try adding results as the first parameter in the callback of the save function, then res.json(results, { message: "Memory Created" }) to see if you are returned anything.
The main difference between the post and the get method is that the post method uses Mongoose, while the get doesn't. If you fail to connect to the database then the response can time out due to memory.save(...) not working as it should. And there are no responses sent outside the callback to save, so if your program never enter it, you will never send a response. The request will time out eventually.
In your model file you register a model on the following line:
module.exports = mongoose.model('Memory', MemorySchema);
Mongoose will then look for data in the memorys collection. If you change it to
module.exports = mongoose.model('Memory', MemorySchema, 'memories');
it will use the memories collection instead. This will make it consistent with the connection-to-db snippet you posted. I don't know if that will fix your issue though. I would suggest changing the connection code to
mongoose.connect(dburl, {
useMongoClient: true
});
instead of the native mongo client. You can add these lines too
mongoose.connection.on('connected', function () {
console.log('Mongoose connected');
});
mongoose.connection.on('error', function (err) {
console.log('Mongoose connection error: ' + err);
});
mongoose.connection.on('disconnected', function () {
console.log('Mongoose disconnected');
});
right after the connection code to help with debugging. Make sure you get connected when starting the app.
If you see an error similar to this Error: Can't set headers after they are sent. in the node terminal window, it might be because you are sending two responses in the post function. If an error occurs while saving it will enter the if(err) block, send a response async then go to the res.json(...) response and send that too.
So you have to return after sending the response to exit the function. Either like this
res.send(err);
return;
or like this
return res.send(err);
Same for the json response.
If that doesn't fix the problem you should either fire up the debugger (node --inspect or nodemon --inspect), or insert a console.log('inside post'); inside the post function to see that you're actually entering it.

How to emit a socket.io response within post request in NodeJS

I have a node server running a react application, integrated with Socket.io. All works fine. I also have an external application that uses the same data. What I want to do is, when the data changes, post to my node server and then in the response, emit to any data to users who are currently subscribed to the socket.
//SERVER CODE LIVES ABOVE HERE...
const io = require('socket.io')(server);
io.on('connection', (socket) => {
socket.on('create data', function(data) {
//a place to create data, once complete triggers everyone subscribed to get an update.
socket.emit('data created', data);
});
});
app.post('/api/datacreated/', function(req, res) {
//HOW DO I EMIT IN HERE?! - this is coming from an external resource
socket.emit('data created', data);
})
Cheers for any time you've got!
Socket is locally scoped. io.sockets is not, so you can do:
app.post('/api/datacreated/', function(req, res) {
//this is coming from an external resource
io.sockets.emit('data created', data);
})

pass an attr to all good responses in sails js

I'm currently working on a angular + sails project. I'm using json web tokens for auth. It works fine but I wanna set a new token for every validated request that my angular app does.
This is my auth policy
passport.authenticate('jwt', function (error, user, info) {
if (error) return res.serverError(error);
if (!user)
return res.send({
message: info.message,
code: info.code,
tokenError: info.name
});
// The token is ok past this line
// I check the user again
User.findOne({ email: user.email }, function (err, thisUser) {
if (err) { return res.send(err); }
if (!thisUser) {
// send a bad response
}
req.user = user;
// This is the new token that I wanna send to the frontend
var newToken = AuthService.createToken(thisUser);
next();
});
})(req, res);
With this policy I can create the new token, but then I would need a way to include this token in every response, this Is the point where I'm stuck.
I gues I could do it manually in every controller action, but this is want I want to avoid
The best way to standardize your responses in Sails is to use the custom responses feature. In short, instead of calling res.send() or res.json() in your controller actions, call res.ok() instead, and then customize the api/responses/ok.js file that is generated with every new Sails app. This is the same response that Sails blueprints use as well!
In your case, you'd want to save the token onto the request object (e.g. req.token) in your policy code, then use that property in your logic inside of ok.js.

NodeJS - RESTful API - Python/JSON - Trigger

I'm working on a little project - completely new to this stuff - and hope you can help me out.
On the base of this project https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4 which is up running and works really great.
The main goal is it to send a UserID over the network - which is already working by python/json - and let the server react on this and show a login with the just sent UserID and an password input.
I already enhanced the server.js with a POST from the python script and when the server is running the terminal recognizes when the UserID is sent.
...
router.route('/bears/:id')
.get(function(req, res) {
Bear.find({‚id': req.params.id}, function(err, bear) {
if (err)
res.send(err);
console.log(‚here i am ...');
});
});
...
I also created a HTML which I thought should always listen (by AJAX) to the post and if the trigger (UserId) is send it should forward to another side with the input field.
So right now I don't really know how to implement that the Server already got the trigger and the HTML forwards the User to the Login?
Let the server handle where the user goes - issuing a 200 for a successful user, or an error 400 if it's a bad request. For example:
router.route('/bears/:id')
.get(function(req, res) {
Bear.find({‚id': req.params.id}, function(err, bear) {
if (err)
res.status(400).send(err); //Send a generic bad request error
else {
res.status(200).render('login', { name: req.params.id }); //Direct client to your login page (this example uses the jade template egine)
});
});
I hope this is what you're looking for :)

Categories