kk415kk
kk415kk

Reputation: 1247

Sails.js: Subscribing a User to specific actions on a Request

In my Sails project, I have a User model/controller and a Request model/controller, as well as a Dashboard controller. A user can make a request for data using RequestController.create, and an administrator can approve it using RequestController.grant.

What I want to do is to notify a user whenever one of his/her requests is approved (updated). In RequestController.grant, I call Request.publishUpdate(...), and in my DashboardController.display, I call

Request.find(req.session.user.id, function(err, requests) { 
    ... 
    Request.subscribe(req, requests, ['update']) 
    ... 
});

Then, in the view /dashboard/display, I put in <script> tags:

<script>
// Socket handling for notifications
io.socket.on("request", function(obj) {
    alert(obj.verb);
    alert(obj.data);
    alert(obj.previous);
});
</script>

However, upon approving a user's request and going to the dashboard, no alerts show up. The script for sails.io is already loaded, with no errors in the console. Am I doing something wrong?

Upvotes: 0

Views: 574

Answers (1)

sgress454
sgress454

Reputation: 24958

The likely problem here is that you're using Request.subscribe in an HTTP call. I'm assuming that's the case since it seems like you're problem using DashboardController.display to display a view. In this case, the Request.subscribe doesn't do anything at all (it should really display a warning) because it can't possibly know which socket to subscribe!

If you'd like to keep your controller logic the same (you might be using the requests array as a view local to bootstrap some data on the page), that's fine; a quick refactor would be to test whether or not its a socket call in the action:

// Also note the criteria for the `find` query below--just sending an
// ID won't work for .find()!
Request.find({user: req.session.user.id}, function(err, requests) { 
    ... 
    // If it's a socket request, subscribe and return success
    if (req.isSocket) {
        Request.subscribe(req, requests, ['update']) 
        return res.send(200);
    } 
    // Otherwise continue on displaying the view
    else {
        ... 
        return res.view('dashboard', {requests: requests});
    }
});

Then somewhere in your view call io.socket.get('/dashboard/display') to subscribe to request instances.

You could also use blueprints to subscribe to the requests from the front end, doing something like io.socket.get('/request?user='+userId), if you put the user ID in the locals and add it somewhere in your view template, e.g. <script>var userId=<%=user.id%></script>.

Upvotes: 1

Related Questions