Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inform ember-data about server changes

I am currently planning a complex application using ruby on rails and ember.js. What I have seen about ember-data so far is that it caches records automatically; post.comments will first result in a Ajax-call to fetch all comments for the given post, but if the user visits the same route the next time, it will just fetch the records from the store-cache.

The problem is: What if another user added a comment to this post? How to tell ember it has to reload its cache because something changed?

I already thought about a solution using websockets to tell clients which stuff to reload - but I don't think this is best-practice. And in addition, I can't imagine this isn't a common problem, so I am wondering what other developers are doing to solve this issue.

like image 500
Toni Avatar asked May 19 '14 14:05

Toni


People also ask

How does Ember data work?

Ember Data is a model library that manages finding data, making changes, and saving it back to the server. It's a bit like an ORM in that it abstracts the underlying persistence mechanism behind an easy to use API. If you're familiar with using ORMs, you will find Ember Data easy to work with.

What is the use of Ember js?

js is an open-source JavaScript web framework that utilizes a component-service pattern. It allows developers to create scalable single-page web applications by incorporating common idioms, best practices, and patterns from other single-page-app ecosystem patterns into the framework.

What is store in Ember?

The store contains all of the data for records loaded from the server. It is also responsible for creating instances of Model that wrap the individual data for a record, so that they can be bound to in your Handlebars templates. Define your application's store like this: app/services/store.js.


1 Answers

I tried to implement model updating in (experimental) chat application. I have used SSE: ActionController::Live on server side (Ruby on Rails) and EventSource on 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'm getting each new record from EventSource. Then, if record was created by another client, the application detects it and new record being added to store using ember-data's createRecord. Suppose this logic may have some caveats, but at least it serves well as 'proof of concept'. Chat is working.

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

I have something to say about reloading: you probably don't want to perform full reloading, it's resource-consuming operation. Still, your client side needs some way to know about new records. So, getting new records one-by-one via SSE is probably the best option.

like image 113
denis.peplin Avatar answered Oct 05 '22 04:10

denis.peplin