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


#1

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…


#2

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.


#3

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)


#4

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'))	

				  })
	
		  }
 	},
	
});

#5

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


#6

Can I see your component template?


#7

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


#8

Of course you should use dataItems in template now


#9

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}}

#10

Did your clientList populate at all?


#11

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


#12

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…


#13

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…


#14

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: “Проводник”}


#15

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


#16

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’?


#17

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


#18

ok, will try, thanks…


#19

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…


#20

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