0

I'm currently working on a application that works with with websockets to implement a real-time chat (along with many other things).

However, I have some issues with a Ember.computed member that observes a Ember.NativeArray.

I tried a few things found while googling the issue, but none of them seem to work! My array is a Ember.NativeArray defined in a service like this:

chatMessages: Ember.A()

My computed property, in my component, is defined as such:

messages: Ember.computed('liveSocket.chatMessages', function() {
  return this.get('liveSocket').get('chatMessages').toArray().reverse();
}),

And I set objects to the array in my service as follows:

this.get('chatMessages').set(data.id, null);

If I observe the array directly, nothing changes (I may be confused with that, but isn't that the point of embedding an array in a Ember.Array object?). Now, I can easily watch the array for new elements, by observing the liveSocket.chatMessages.length property. Everything works well and new messages are correctly added. The problem is when I try to remove messages. The websocket server is badly engineered, and changing it is a non-possibility: it doesn't remove the indexes of deleted messages, and returns null objects instead.

So I not only need to watch changes to the array's length, but also to its elements. I tried adding liveSocket.chatMessages.@each to my observed elements list, but that doesn't work either. To sum it up:

// Never updates
Ember.computed('liveSocket.chatMessages', ...)

// Updates only on push/pop (as expected)
Ember.computed('liveSocket.chatMessages.length', ...)

// Still only updates on push/pop
Ember.computed('liveSocket.chatMessages.length', 'liveSocket.chatMessages.@each', ...)

Am I missing something here? Is there a way to observe an array's length and all the elements it contains? Is my approach to this wrong? I am using Ember 2.6 and Ember Data 2.6.1.

Thanks!

1 Answer 1

2

I assume in chatMessages you have objects with property title.

So if you want to trigger every time title of any objects changed, you need to compute on :

Ember.computed('[email protected]', ...);

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your answer! Unfortunately I have pure javascript objects in my array that may be null, so I don't think I can reliably observe their properties, as I need to fire my computed value when the object itself is set to null.
@blue I don't understand what do you mean from setting null an object? If an object is to be null so remove that
Sorry for the delay, I had a deadline yesterday and I needed to work on other things. The thing is, I can't really remove it as the server is at the moment very dependant on array indexes. So instead, it sets deleted messages to 'null'. The client needs to do more or less the same thing as some payloads come with array indexes in the data, so I need to retain the exact same order.
@blue I think it's better you wrap your server objects. Because setting null a object is not meaningful. I assume you don't use ember-data
No, I don't use Ember Data as some payloads are data-less, so I feel using it would be illogical. I'll probably end up wrapping my objects as you suggested, doing it the way I started is getting bad for my mental health! I don't get the benefit of using Ember.Array if I can't observe it, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.