[SOLVED] Sort by unsaved property of model


#1

Tell me please, how can i sort model by unsaved prop.

I have a User model, and she uses rest api adapter, but i set status online through websockets, and sort is not refresh until i make “user.save()”. I dont wont use save() because it generate too much requests.

Ember 2.2

sortProperties: [‘online’], sortByOnline: Ember.computed.sort(‘model’, ‘sortProperties’)

Any ideas?


#2

When you use

sortByOnline: Ember.computed.sort(‘model’, ‘sortProperties’)

It just sort the model and store that in the computed property sortByOnline which means that the user model will remain undisturbed.

If you want the sorted change to be reflected back in the User model, then, make the sortByOnline and model two way binded.


#3

Can you explain how you’re setting that status? Are you pushing an updated payload into the store or are you calling user.set?

Perhaps you can provide an ember-twiddle or jsbin that demonstrates the problem.


#4

i call user.set(‘online’, true); or false if offline :slightly_smiling:. if i call user.save(), sort is applied.

too much code for jsbin, but i can describe in detail: I have a service

import Ember from 'ember';
export default Ember.Service.extend({
  store: Ember.inject.service('store'),
  ws: null,
  init: function() {
    this._super(...arguments);
    var self = this,
      ws = Ember.$.ws("ws://ws");
    ws.onmessage = function(evt) {
      var edata = evt.data,
        data = JSON.parse(edata);
      //...
      if (data.type == 'users') {
        self.get('store').peekAll('user').forEach(user => {
          if (data.users.contains(user.get('id'))) {
            user.set('online', true);
          } else {
            user.set('online', false);
          }
          // user.save();
        });
      }
      //...
    }

    this.set('ws', bullet);

  }
});

Route

import Ember from 'ember';

export default Ember.Route.extend({
  queryParams: {
    username: {
      refreshModel: true
    }
  },
  model: function(params) {
    return this.store.query('user', params);
  }

});

and Controller

import Ember from 'ember';

export default Ember.Controller.extend({
  queryParams: ['username'],
  username: "",
  sortKeys: ['online'],
  sortedClients: Ember.computed.sort('model', 'sortKeys')
});

#5

@SpaceMaster – I made this ember-twiddle to demo this behavior: https://ember-twiddle.com/7d762165a6f75d77991f?openFiles=application.controller.js%2Capplication.template.hbs . It seems to work fine for me. Can you figure out what’s different between that twiddle and your app?

I really really doubt this is the problem, can you try using Ember.run.bind on your WebSocket message? This ensures a run loop is active when your app receives messages. IE:

export default Ember.Service.extend({
  store: Ember.inject.service('store'),
  ws: null,
  init: function() {
    this._super(...arguments);
    var ws = Ember.$.ws("ws://ws");
    ws.onmessage = Ember.run.bind(this, function(evt) {
      var edata = evt.data,
            data = JSON.parse(edata);
      //...
      if (data.type == 'users') {
        this.get('store').peekAll('user').forEach(user => {
          if (data.users.contains(user.get('id'))) {
            user.set('online', true);
          } else {
            user.set('online', false);
          }
          // user.save();
        });
      }
      //...
    });
  }
});

Also notice that I was able to change self to just using this. An added benefit.


#6

Thank you! I find problem in scroll component, when i use jScrollPane

import Ember from 'ember';

export default Ember.Component.extend({
  classNames: ['members', 'tiny-scroll'],
  didInsertElement() {
    this.$().jScrollPane({
      autoReinitialise: true,
      autoReinitialiseDelay: 200,
      contentWidth: "0px"
    });
  }
});

I will think about replacing the library.