0

I have the following ChatPanelComponent in which I have a created getSocket method to get a socket and called the onopen EventListener when the socket is connected.

import { AfterViewInit, Component, ElementRef, OnDestroy, OnInit, QueryList, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core';
import { NgForm } from '@angular/forms';
import { HttpClient } from '@angular/common/http';

import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
import { ChatPanelService } from 'app/layout/components/chat-panel/chat-panel.service';
import { WebsocketService, UserService } from 'app/core/services';

@Component({
    selector     : 'chat-panel',
    templateUrl  : './chat-panel.component.html',
    styleUrls    : ['./chat-panel.component.scss'],
    encapsulation: ViewEncapsulation.None
})
export class ChatPanelComponent implements OnInit, AfterViewInit, OnDestroy
{
   contacts: any[];
   chat: any;
   selectedContact: any;
   ws: any;
   ws_url: any;
   user_id: any;
   
   constructor(
        private _chatPanelService: ChatPanelService,
        private _user: UserService,
        private _WebSocket: WebsocketService,
   )

   ngOnInit(): void
   {
       this.ws_url = 'http://localhost:8000/thread/';
       this.user_id = this._user.getUser().id;
       this.getSocket(this.user_id);
   }

   getSocket(id: any) {
       this.ws = this._WebSocket.connect(this.ws_url+id+'/');
 
       this.ws.onopen = function(e){
           console.log("WEBSOCKET OPEN", e);
       }

       this.ws.onmessage = function(e) {
           this.showMessage(e);
       }
  }

  showMessage(msg: any){
       console.log("MESSAGE", msg);
  }
}

I want to call the showMessage(msg: any) method when the onmessage event occurs and and pass the event data to the showMessage() method. But when the method is called it gives the following error:

ERROR TypeError: this.showMessage is not a function
    at WebSocket.ws.onmessage [as __zone_symbol__ON_PROPERTYmessage]

I can't think of any other ways to call the method. I need help in this. Thanks in Advance!

Ajay Lingayat
  • 1,465
  • 1
  • 9
  • 25

2 Answers2

2

Have you tried using arrow function? It   preserves the context.

this.ws.onmessage = (e) => { this.showMessage(e); }

maidi
  • 3,219
  • 6
  • 27
  • 55
1

Because event callbacks are executed outside Angular's context, this refers to callback event's context rather than angular components. so this does not refers to component's context anymore.

you can save value of this inside any other local variable and use that:

getSocket(id: any) {
       this.ws = this._WebSocket.connect(this.ws_url+id+'/');
 
       this.ws.onopen = function(e){
           console.log("WEBSOCKET OPEN", e);
       }

       const self = this; // <- store this value in a local variable

       this.ws.onmessage = function(e) {
           self.showMessage(e); //<- use that local variable containing value of component's context
       }
}

For more detail about it please refer to this answer: https://stackoverflow.com/a/20279485/9722122

Mustahsan
  • 3,852
  • 1
  • 18
  • 34