Why i can't read variable on callback function

I fill the input form with β€œI am six years old.” and press send button.
why the output is

I am six years old.
this.history_msgs is false

home.html

<ion-content padding>
  <ion-list>
    <ion-item *ngFor="let m of history_msgs">{{ m }}</ion-item>
  </ion-list>
</ion-content>
<ion-footer>
  <ion-input placeholder="message..." [(ngModel)]="chat_msg"></ion-input>
  <button ion-button (click)="send()">send</button>
</ion-footer>

home.ts

import { Component, NgZone } from '@angular/core';

import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  socket: any;
  ws_path: string = 'ws://192.168.1.233:8000';
  chat_msg: string = '';
  history_msgs: string[] = ['how old are you?'];
  out_life: string = 'i am in life cycle';

  constructor(public navCtrl: NavController, public ngZone: NgZone) {

    this.ngZone.run(() => {
      this.socket = new WebSocket(this.ws_path);
      this.socket.onmessage = function (e) {
        alert(e.data);

        if (this.out_life) {
          alert('out life true');
        }

        if (this.history_msgs) {
          alert('this.history_msgs is true');
          // this.history_msgs.push(this.chat_msg);
        } else {
          alert('this.history_msgs is false');
        }
      }
    })
  }

  ionViewDidEnter() {
  }

  send() {
    if (this.socket.readyState == WebSocket.OPEN) {
      this.socket.send(this.chat_msg);
      this.chat_msg = '';
    }
  }

}

the problem is, that your callback function is called from the socket and not from your class β†’ the β€œthis” context changed here.

but you can force it, if you use the fat arrow function for your callback

this.socket.onmessage = e => {
  // ...
})

or simple add bind(this) at the end of your function definition:

this.socket.onmessage = function(e) {
  // ...
}.bind(this)
1 Like

Thank you. It works right.:+1: