dchacke / entangled-angular

Client side counterpart to Ruby gem "Entangled" for Angular
MIT License
2 stars 0 forks source link

Is it possible to get all messages after a datetime? #4

Open ffabreti opened 8 years ago

ffabreti commented 8 years ago

Dennis, I am trying to make a chat with your gem where parent/children are chatroom/messages. If I setup Message.all( ), everytime a message is created Message.all() is called and fetches all messages. That is fine when you have a dozen messages, but if you have thousand of messages... So, I thought of passing an object to .all(), like you can do on .create(), so that I can filter messages after some date on Rails controller. Something like: Message.all({last: 'Sat Apr 09 2016 00:32:13 GMT-0300 (BRT)'}, function() {...} )

Would that be possible with current Entangled? How and Where would be better to hack such a feature?

ffabreti commented 8 years ago

Well... this works:

entangled.angular.js:

Entangled.prototype.all = function(params, callback) {
      var aDash = (this.webSocketUrl.match(/\/$/)) ? '' : '/';
      var socket = new WebSocket(this.webSocketUrl + aDash + object2queryString(params));

Rails controller:

def index              # /chat_room/index/?last=2016-04-09T17:47:49.574Z
        broadcast do
            last = chat_room_last
            if last
                @chat_rooms = ChatRoom.where("last_time > ?", last).to_a
            else
                @chat_rooms = ChatRoom.all
            end
        end
    end

But the problem is parameters are statically setup and can never change (because webSockets URL is setup only once)

Maybe I should code a no standard action, not sure how much of the 'magic' will loose on that.

dchacke commented 8 years ago

What you need is what I would summarize as "scoping", such as where clauses etc. Scoping is currently not supported, but is on my todo list.

I'll leave this issue open until this is addressed.

dchacke commented 8 years ago

If it helps, and your performance concern is about the client (such as client side rendering), and not about the server, you can still filter your messages on the client after fetching them:

Message.all(function (err, messages) {
  if (!err) {
    $scope.messages = messages.filter(function (message) {
      return message.createdAt > 2 weeks ago // pseudo code
    });
  }
});

This would at least speed up the rendering of your messages. In this example, the client would ignore messages older than 2 weeks.

Just to be clear, if you have thousands of messages in your database, those will only be loaded the first time you invoke Message.all. After that, only new messages are passed, i.e. one at a time.

ffabreti commented 8 years ago

Thanks. I am concerned about rendering, but also about network transfer time (slow connections like 3G). Yeah, where clauses would be great for that. Maybe better than keeping track of a backlog and asking for message ids 'newer than'.