How to re-render component?

have read a lot of guides and did not understand - how to rerender ember’s component internally? (not by user’s action).

e.g. I have a component that shows a list of objects received from websockets and want to redraw the list when a new object is received:

component js code:

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

const { get, inject } = Ember;

export default Ember.Component.extend({
    didRender() {
	clientList: [],
	doubleClick() {"DoubleClickableComponent was clicked");

		    let socket = new Socket(ws://", {
		      logger: ((kind, msg, data) => { console.log(`!!!! ${kind}: ${msg}`, data) })

		    //socket.connect({user_id: "123"})
		    var $guid = "Sashka";
			socket.connect({client_id: $guid, client_type: "browser", client_name: "anonymous"});

		    var chan ="rooms:666", {});
			           //.receive("error", resp => { console.log("error on JOIN", resp) } )
					   //.receive("ignore", resp => { console.log("auth error", resp) } )
			           .receive("ok", resp => { console.log("join ok", resp) } )
			           //.after(10000, resp => { console.log("Connection interruption", resp) })
		    chan.onError(e => console.log("something went wrong", e))
		    chan.onClose(e => console.log("channel closed", e))
		    $"keypress").on("keypress", e => {
		      if (e.keyCode == 13) {
		        chan.push("new:msg", {user: $username.val(), body: $input.val()})
			chan.on("join", obj => {
				console.log("rcvd JOIN", obj)
			chan.on("client:connected", obj => {
				console.log("rcvd CLCND", obj)
		    chan.on("new:msg", msg => {
		      scrollTo(0, document.body.scrollHeight)

		    chan.on("user:entered", msg => {
		      var username = this.sanitize(msg.user || "anonymous")
		      $messages.append(`<br/><i>[${username} entered]</i>`)

		return true;

Components tamplate:


websockets sample

<div class="page">
  <div class="content-padded">
    {{#each messages as |message|}}
    <div class="form-control">
      <label>New Message</label>
      {{input value=newMessage class="form-control"}}
      <button class="btn" {{action 'sendMessage'}}>Send Message</button>
<div class="footer">

click here!

Objects List:

{{#each clientListD as |client|}}

the problem is that when this.get(‘clientList’).push(obj) happens, the template is not redrawing the list, i want to redraw it correctly after the list is changed. how?

It is not the good solution but you can force the component to update:

Wrap your template code in an

{{#if myTemp}}
       //re render component goes here

and then just update the myTemp variable → true / false

This will force update the component.

some time some code is still runing then it is better to use


This is a really bad idea and no one should need to do this.

The issue in the original post is he/she was mutating an array without going through any of the Array,proto extension methods or Ember.NativeArray methods that will understand a change occurred (pushObject, addObject, removeAt, insertAt, etc.etc.).


1 Like

Your clientList should be defined like: clientList: A() (Ember array, at Ember.A) and to push use this.get('clientList').pushObject(obj).

Besides that, I would handle key presses with Ember (see keyPress), not registering a jQuery once.