Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch when a user leaves the page in Meteor and/or Iron router?

I'm trying to catch when a user leaves from my Meteor application (version 1.2.0.2) ; something equivalent to the SocketIO disconnect() on the server side.

The user could close his browser, go to another website or simply refresh the page and it would fire anyway

Surprisingly, i'm searching on Internet and everything is mixed up, nothing works properly. I thought Meteor was literally based on this magic-live processing so it must manage this event in a way or another.

Iron router documentation specify this :

onStop: Called when the route is stopped, typically right before a new route is run.

I also found Router.load and Router.unload but none of them work. This is my current [not working] code which is quite simple

Router.configure
  layoutTemplate: 'MasterLayout'
  loadingTemplate: 'Loading'
  notFoundTemplate: 'NotFound'

Router.onStop (->

  console.log('Try to stop')
  Users.insert({

    name: "This is a test"
    lat: 0
    lng: 0

    })

)

Am I doing something wrong here ? How do you catch this event in my app ?

like image 652
Laurent Avatar asked Oct 26 '15 18:10

Laurent


2 Answers

You need to attach to the onStop of the route, not the router. For instance:

Router.route('/', {
    onStop: function() {
        console.log("someone left the '/' route");
    }
});

Another option is to use the onStop event of subscriptions. That is probably the option most similar to the socketio disconnect you mentioned. You can find an example of that in the typhone source code.

like image 152
Christian Fritz Avatar answered Oct 15 '22 20:10

Christian Fritz


There were two solution working, I found the 2nd and best one by searching in the API Documentation for a while.

First solution : working with subscribe & publish

Anywhere in the controller / front-end side you must subscribe to a collection

# in coffee
@subscribe('allTargets')

# in javascript
this.subscribe('allTargets')

Afterwards you just have to publish and add a onStop listener. This example will take a Targets collection I already defined somewhere before, it just gets all the entries.

# in coffee
Meteor.publish 'allTargets', ->

  @onStop ->

    # Do your stuff here

  return Targets.find()

# in javascript
Meteor.publish('allTargets', function() {

  this.onStop(function() {

      // Do your stuff here

  });

  return Targets.find();

});

You have to be careful not to return Targets.find() before you set the onStop listener too. I don't think it's a perfect solution since you don't listen to the connection itself but the changes of a collection.

Second solution : working with DDP connection

I realized through the Meteor API Documentation we can directly listen to the connection and see if someone disconnect from the server-side.

To stay well-organized and clean within my Meteor Iron project I added a new file in app/server/connection.coffee and wrote this code

# in coffee
Meteor.onConnection (connection) ->

  connection.onClose ->

    # Do your stuff

# in javascript
Meteor.onConnection(function(connection) {

  connection.onClose(function() {

    // Do your stuff

  });

});

You can manage datas with connection.id which's the unique identifier of your browser tab. Both solutions are working well for me.

If you use Meteor.userId through their accounts system, you can't use it outside a method in the server-side so I had to find a workaround with the connection.id.

If anyone has a better solution to manage connections while getting this kind of client datas, don't hesitate to give your input.

like image 38
Laurent Avatar answered Oct 15 '22 19:10

Laurent