Search code examples
javascriptangulartypescriptasynchronouses6-promise

Javascript, solution needed for async issue


Currently creating an application using Angular, socket.io and express. However, I run in an async issue which I have a hard time getting a solution for. Here is the code:

  export class WebsocketService {

  this.socket;

  public connect() {
    const token = sessionStorage.getItem('token');
    this.socket = io('http://localhost:3000', { query: { token: token } });
  }

  public getSocket () {

      // this function should only return this.socket when it is available

      return this.socket;

  }

The idea is that first somewhere in the application somewhere there is connected once with the websocket, the io functions is thus called once:

    this.socket = io('http://localhost:3000', { query: { token: token } });

Then in rest of the application the this.socket property should be passed around. However, this.socket should always return the object and should wait for it if it isn't present.

The implementation should also deal with the other parts of the application who try to call getSocket and get returned undefined. Basically, getSocket should never return undefined it should wait for connection and then return this.socket.

I tried playing around with promises a bit but I can't seem to find an elegant solution.


Solution

  • I do not know why you need the connect method , but here is one approach

    export class WebsocketService {
    
      getSocket() {
    
        // this function should only return this.socket when it is available
    
        if (!this.socket || (this.socket && this.socket.disconnected)) {
    
          this.socket = new Promise((resolve, reject) => {
    
            const token = sessionStorage.getItem('token');
            const s = io('http://localhost:3000', { query: { token: token } });
    
            s.on('connect', () => {
              console.log(socket.connected); // true
              resolve(s);
            });
    
            s.on('disconnect', () => {
              console.log(socket.disconnect); // true
              reject(s);
            });
          });
        }
    
        return this.socket;
      }
    }
    

    Then, usage is:

    service.getSocket().then(socket => {
        // Use the socket
    });
    

    Or with async/await:

    const socket = await service.getSocket();
    // Use the socket