Inform ember about changes in the server

I am currently planning a complex application using ruby โ€‹โ€‹on rails and ember.js. What I saw about ember data is that it automatically caches entries; post.comments will first cause Ajax to retrieve all the comments for the given post, but if the next time the user visits the same route, he will simply retrieve the entries from the repository.

Problem: what if another user added a comment to this post? How to tell ember, it has to reload its cache because something has changed?

I already thought of a solution using websockets to tell clients what to reboot, but I don't think this is the best. And besides, I canโ€™t imagine that this is not a general problem, so I wonder what other developers are doing to solve this problem.

+6
source share
4 answers

If you just want to get rid of caching, you can force reload every time the user navigates to route comments. But it depends a lot on what you are trying to accept, I hope that comments is just an example.

If you want your ui automatically update with changes on the server, you need some communication with the server, some kind of polling mechanism like websocket or polling from webworker . Then you can reload list the modified records sent from the server. You are probably on the right track.

You can also take a look at the standalone orbitjs library, which integrates well with Ember. This is more useful if you need local storage, as well as for managing multiple data sources.

+1
source

I tried to implement a model update in a (experimental) chat application. I used SSE : ActionController::Live on the server side (Ruby on Rails) and EventSource on the client side.

Simplified code:

 App.MessagesRoute = Ember.Route.extend({ activate: function() { if (! this.eventSource) { this.eventSource = new EventSource('/messages/events'); var self = this; this.eventSource.addEventListener('message', function(e) { var data = $.parseJSON(e.data); if (data.id != self.controllerFor('messages').get('savedId')) { self.store.createRecord('message', data); } }); } } }); App.MessagesController = Ember.ArrayController.extend({ actions: { create: function() { var data = this.getProperties('body'); var message = this.store.createRecord('message', data); var self = this; message.save().then(function (response) { self.set('savedId', response.id); }); } } }); 

The logic is simple: I get every new entry from EventSource. Then, if the record was created by another client, the application detects it and adds a new record to the repository using ember-data createRecord . Suppose that this logic may have some reservations, but at least it serves as a โ€œproof of conceptโ€. Chat is working.

Full sources are available here: https://github.com/denispeplin/ember-chat/

I need to say something about rebooting: you probably don't want to perform a full reboot, this is a resource-intensive operation. However, your client side needs some way to find out about new entries. Thus, getting new records individually through SSE is probably the best option.

+1
source

This is a really common problem with any web application, no matter what structure you use. From my point of view, there are two main options. One: you have a service that checks the server to check if there are any changes that require a reboot of some of your models so that this service returns these model identifiers and updates them. Another option, as you suggested, is using websocket and push notifications of model changes / new models.

I would prefer to actually just send the comment model and paste it into the Ember repository and the associated post object. This will reduce the need for a server with a hard update of your model. I am currently using this method with my Ember application, where there is an object that contains overview data based on all models of my application, and when changes are made to the backend, my websocket server pushes new overview data to my application.

UPDATE :: I meant that this is a comment, not an answer, well.

0
source

I had the same problem with mobile app development. Although websockets seemed like the first answer, I was worried about scalability issues with limited server resources. I decided to stick with an Ajax call to retrieve recently modified records. Thus, server resources are used only if the user is active. However, as others have pointed out, returning all comments every time you need data, your caching is useless and slow. I suggest updating the rails server to accept an additional timestamp. If no timestamp is specified, then each comment is retrieved. If a timestamp is specified, return comments only where the updated_at >= column is the updated_at set. Thus, if no comments have been added or changed since your last call, you will quickly receive an empty list and you can continue. If the results are returned, you can combine them with the existing list and show updated comments.

An example of retrieving newly created or modified comments

 if params.has_key?(:updated_since) comments = Post.find(params[:id]).comments.where("updated_at >= ?", params[:updated_since]) else comments = Post.find(params[:id]).comments end 
0
source

Source: https://habr.com/ru/post/969538/


All Articles