How to change items in array property and render the change?

I have an array property in the component, and it is rendered in associated template

when I add an object to that array using the pushObject method - template is refreshed and it’s ok

but how should I change the content of the array and make template render it?

e.g. I tried to change the copy of my array and make this.set(‘clientList’, bufAr) - and it does not redraw the template…

Define a computed property and render that.

dataItems: Ember.computed('mainItems.@each.key', function(){ return this.get('mainItems'); })

Now when you change key of any objects, your data is rerendered.

ok, I tried that this way:

import Ember from 'ember';
import Phoenix from 'ember-phoenix-chan';
const {Socket, Channel, LongPoll, Ajax, Presence} = Phoenix;

const { get, inject } = Ember;

export default Ember.Component.extend({

	 clientList: [],
	 dataItems: Ember.computed('clientList.@each.caption', function(){ return this.get('clientList'); }),
	 
 	actions: {
		connect() {

////some excessive code cutted here
			
				chan.on("status:changed", obj => {
			
					this.get('dataItems').forEach(
						function(item, i, arr) {
							if (item.id == obj.id) {	
								arr[i] = obj   //this changes caption property of item				
							}
						})
					
					console.log("dataItems: ", this.get('dataItems'))	

				  })
	
		  }
 	},
	
});

and still the component is not re-rendered even when i see that dataItems contain new object item

also, could you please explain what does ‘clientList.@each.key’ mean? (did not see such case in the guide)

As I said, I assumed you want to change key property of each item. Now I see in you your sample code you don’t have key property. I change your sample code like this :

 import Ember from 'ember';
import Phoenix from 'ember-phoenix-chan';
const {Socket, Channel, LongPoll, Ajax, Presence} = Phoenix;

const { get, inject } = Ember;

export default Ember.Component.extend({

	 clientList: [],
	 dataItems: Ember.computed('clientList.[]', function(){ return this.get('clientList'); }),
	 
 	actions: {
		connect() {

////some excessive code cutted here
			
				chan.on("status:changed", obj => {
			
					this.get('clientList').forEach(
						function(item, i, arr) {
							if (item.id == obj.id) {	
								arr[i] = obj				
							}
						})
					
					console.log("dataItems: ", this.get('dataItems'))	

				  })
	
		  }
 	},
	
});

ok, applied it for ‘clientList.’ now and I see that component is still not re-rendered (but dataItems return updated content)… any thoughts?

Can I see your component template?

have an idea… should I now refer to data dataItems from the template instead of clientList ?

Of course you should use dataItems in template now

still no luck:))

{{yield}}

<button {{action 'connect'}}>Connect</button><br>


<br>
Objects List:
<br>
<table border=1>
<tr>
  <td>id</td>
  <td>username</td>
  <td>computername</td>
  <td>application</td>
  <td>caption</td>
</tr> 
{{#each dataItems as |client|}}
<tr>
  <td>{{client.id}}</td>
  <td>{{client.username}}</td>
  <td>{{client.computername}}</td>
  <td>{{client.application}}</td>
  <td>{{client.caption}}</td>
</tr>  
{{else}}
  Sorry, nobody is here.
{{/each}}

</table>
<br>
clientList.Length = {{clientList.length}}

Did your clientList populate at all?

If your list populated and you have a clientList that its size has no change, so I suggest you copy obj to item

Use Ember.assign for this

sorry, what does it mean? clientList is filled with some objects, I’m changing the content of one of objects just by assigning another object to existing object…

I need to replace content of one of array items (object) or its properties. when I try to change the properties directly from forEach loop, I cannot make this.get(‘clientList’).item because ‘this’ is not working in the loop… so i tried to replace the whole item object…

1 Like

ok, changed arr[i] = obj to Ember.assign(arr[i], obj)

and got this:

Uncaught Error: Assertion Failed: You must use Ember.set() to set the username property (of [object Object]) to istok.

sample object content: {username: “istok”, id: “96”, computername: “ISTOKPC”, caption: “wsClientDemo”, application: “Проводник”}

If both array items and obj is simple object Ember.assign should work. So anyway you can create a util function to copy from obj to item. And then my first sample code would work. That has clientList.@each.id

what is the idea of Ember.assign if it still requires Ember.set() for each property of the item?

and how may I use a function to assign item’s properties if I cannot use ‘this’ inside of foreach function loop and as a result cannot make ‘set’ or ‘get’?

Set var self = this; before loop and use self in loop.

Actually you don’t need this in loop.

Copy each property from obj to item in loop. You have 5 props

ok, will try, thanks…

no luck… .how to make set of an array’s item’s property?

tried like this: self.set(self.get(‘clientList’)[i].caption, obj.caption) self.set(self.get(‘clientList’)[i].application, obj.application)

I don’t understand how to refer to caption property in self.set…

I said you don’t need self in loop. Even this. I wrote that for just know.

Please copy one-by-one each property from obj to item