Nutan Kumar Lade
Nutan Kumar Lade

Reputation: 47

Meteor: Application crashing

I have the following method in one of the controller. When I'm calling this method from html code using {{ getLastMessage }}, the browser is crashing. There are multiple calls to this method and the browser is unresponsive. Could someone please help to resolve this issue?

$scope.getLastMessage = function(userId) {
   var query = {};
   query['uid'] = userId;
   var lastMessage = $meteor.collection(function(){
      return Chats.find(query, {fields: {'_id':1, 'content':1, 'uid':1}});
   });
   console.log(lastMessage);
   return lastMessage;
};

Upvotes: 0

Views: 92

Answers (1)

JacobWuzHere
JacobWuzHere

Reputation: 913

I think your issue is that getLastMessage is a function, and not a property, so your code is the equivalent of {{ function(){} }} that is never even getting invoked. You need to actually invoke the function like {{getLastMessage()}} or immediately invoke the function on your controller.

If I may offer you a slightly easier solution (though maybe less efficient):

If you haven't already bound the collection to a scope variable yet, you would want to do something like:

// SERVER CODE -- put in your /server directory

// NB: I am only publishing the specific user's (uid) chats in case someone 
//     finds this through Google and by accident creates a vulnerability
//     unintentionally. Feel free to change the Mongo query if you want to     
//     publish all chats to all users 

Meteor.publish("Chats", function () {
  return Chats.find({uid:this.userId}, {fields: {'_id': 1,'content': 1,'uid': 1}});
});

// CLIENT CODE

$scope.chatsCollection = $scope.$meteorCollection("Chats").subscribe("Chats");
// lastMessage should be updated reacitvely -- no need to run a function
$scope.lastMessage = $scope.chatsCollection.slice(-1)[0];

With that said that slice assumes that the Meteor Collection is appending new documents to the end chronologically, so the reality may not be so simple. The $scope.chatsCollection has all the methods of an array, so you can sort it or use something like underscore.js to peroform queries on it.

Another approach you might consider taking would be to use the pure Meteor Cursor.observe method -- which it looks like you were kind of following in your initial approach. One benefit here is that you can perform any necessary sort operations on the Mongo query, which might be more efficient.

I think that would look something like:

// CLIENT SIDE CODE
// Initial assignment 
$scope.lastMessage = Chats.find({uid:Meteor.userId(), {
                fields: {
                    '_id': 1,
                    'content': 1,
                    'uid': 1
                },
                sort: {INSERT YOUR SORT HERE, e.g. by creation time}
            })
        .fetch().slice(-1).pop();



// Subscription to changes made on the query
   Chats.find({uid:Meteor.userId(), {
            fields: {
                '_id': 1,
                'content': 1,
                'uid': 1
            },
            sort: {INSERT YOUR SORT HERE, e.g. by creation time}
        })
    .observe({added: function(document){$scope.lastMessage = document}});

Upvotes: 1

Related Questions