Hitesh Balar
Hitesh Balar

Reputation: 181

How to update DOM when receive socket message in angular2?

I'm trying to implement chat application with angular2 + socket.io, I'm able to get message back from server but as soon as I get message back how to update DOM. I have done like this.messages.push(message) but this has no effects.

This what I'm doing

Home.ts

import {Component} from 'angular2/core';
import * as io from 'socket.io-client';
import * as _ from 'lodash';

const socket = io.connect();

const template: string = require("./home.html");
const style: string = require("./home.scss");

@Component({
  selector: 'home',
  template: template,
  styles: [style]
})
export class Home {

  private _user: any;
  private messages: any;
  private draftMessage: any;

  constructor() {
    this.messages = {};

    socket.on("on:send-message", (data) => {
      this.messages.push(data);
      console.log("message :", data);
    });

    socket.on("on:joined-room", (data) => {
      console.log("joined");
    });
  }

  get user() : any {
    return this._user;
  }

  onEnter(event: any): void {
    event.preventDefault();
    socket.emit("on:send-message", this.draftMessage);
  }

}

This is my express route

 socket.on("on:send-message", (data) => {
    socket.emit("on:send-message", data);
 });

Home.html

<div class="panel-body msg-container-base">
     <ol class="chat">
         <li class="self" *ngFor="let row of messages">
             <div class="avatar"><img src="/avatar.png"/></div>
              <div class="msg">
                 <p>{{row}}</p>
                 <time>20:18</time>
              </div>
         </li>
     </ol>
</div>

How to implement ChangeDetectorRef or Detection strategy in angular2.

Thank You.

Upvotes: 0

Views: 508

Answers (1)

Thierry Templier
Thierry Templier

Reputation: 202196

I think that the problem is that you initialize your socket outside Angular2 (a component or a service) so the code that receives events from the socket is executed outside an Angular2 zone. So the framework can't detect changes.

Either you explicitly run this code in a zone using NgZone:

@Component({
  selector: 'home',
  template: template,
  styles: [style]
})
export class Home {
  private _user: any;
  private messages: any;
  private draftMessage: any;

  constructor(private ngZone:NgZone) {
    this.messages = {};

    socket.on("on:send-message", (data) => {
      this.ngZone.run(() => {
        this.messages.push(data);
        console.log("message :", data);
      });
    });

    (...)
  }
}

Either you initialize the socket in the context of Angular2.

Upvotes: 2

Related Questions