Learn how to resubscribe and reconnect to a WebSocket using TypeScript

In my Ionic3 app, there is a specific view where I connect to a websocket observable/observer service upon entering the view:

subscribtion: Subscription;

ionViewDidEnter() {
    this.subscribtion =  this.socket.message.subscribe(msg => {
    let configs = <Configs>msg.data 
    this.inputs = configs.inputs;
  });
  this.socket.message.next(this.enterMessage);
}

When leaving the view, I unsubscribe from the websocket:

ionViewWillLeave() {
  this.socket.message.next(this.quitMessage);
  this.subscribtion.unsubscribe();
}

The issue arises when reentering the view, as it does not reconnect to the websocket. How can I resolve this?

Below are the details of the socket and websocket.ts :

@Injectable()
export class SocketProvider {

public message: Subject<Message>;

  constructor(private socket: WebsocketProvider, @Inject('server') private server) {
    console.log('Hello SocketProvider Provider');
    let wsAddr = this.server.webSocketUrl();
    this.message = <Subject<Message>>socket
    .connect(wsAddr)
    .map((response: MessageEvent): Message => {
        let data = JSON.parse(response.data);
        return data;
    })
  }

  }


private subject: Rx.Subject<MessageEvent>;

public connect(url): Rx.Subject<MessageEvent> {
  if (!this.subject) {
    this.subject = this.create(url);
    //console.log('successfully Connnect: ' + url);
  }
  return this.subject;
}

public create(url): Rx.Subject<MessageEvent> {
let ws = new WebSocket(url);

let observable = Rx.Observable.create(
  (obs: Rx.Observer<MessageEvent>) => {
    ws.onmessage = obs.next.bind(obs);
    ws.onerror = obs.error.bind(obs);
    ws.onclose = obs.complete.bind(obs);
    return ws.close.bind(ws);
  }
)

let observer = {
  next: (data: Object) => {
    if (ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify(data));
    }
  }
}

return Rx.Subject.create(observer, observable);
}
}

Answer №1

After much troubleshooting, I discovered the solution:

I decided to refactor the code within the constructor of socket.ts into a separate connect function that I then invoked in IonViewEnter(), causing a reinitialization of the WebSocketProvider object:

constructor(private socket: WebsocketProvider, @Inject('server') private server) {
  console.log('Greetings from SocketProvider Provider');
}

connect() {
  console.log("Attempting to establish websocket connection");
  this.socket = new WebsocketProvider;
  let wsAddr = this.server.webSocketUrl();
  //let wsAddr = 'ws://192.168.0.110:8181';
  this.message = <Subject<Message>>this.socket
  //.connect('wss://echo.websocket.org')
  .connect(wsAddr)
  .map((response: MessageEvent): Message => {
    try {
      let data = JSON.parse(response.data);
      return data;
    } catch(e) {
      alert(e);
      console.log("Received invalid JSON message: ");
      console.log(response.data);
    }
  })  
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When trying to generate a popOver in Ionic, an error message "<TypeError: ev.target.getBoundingClientRect is not a function>" may be displayed

I'm currently working on implementing a popover that appears when a mouse click event is triggered. However, I've encountered an issue where the Create() method of the popover gets called upon event activation, but I keep receiving the following ...

What are the top tips for creating nested Express.js Queries effectively?

I'm currently exploring Express.js and tackling my initial endpoint creation to manage user registration. The first step involves verifying if the provided username or email address is already in use. After some investigation, I devised the following ...

How can I design a Typescript interface that accommodates both strings and other data types?

I am working on designing an interface that allows for an array of objects and strings to be stored. For instance: const array = [ '', {id: '', labels: ['']} ] I attempted to achieve this using the following code: export ...

Retrieve information using Angular's EventEmitter

Recently I started learning Angular and encountered a challenging issue that has kept me occupied for the past few hours. I have implemented a parent-child relationship between two components, with a need to share a boolean variable from the parent to the ...

Using Angular filter pipe to customize markers in Leaflet maps

I am currently working on a select element called district, which lists all the districts in the city. My objective is to apply a filter that will dynamically display only the leaflet markers corresponding to the selected district on the map. Any suggesti ...

Is it possible to determine the type of a variable by simply clicking on it in IntelliJ (specifically in typescript)?

Having the ability to hover over a variable and see the expected type in TypeScript would be incredibly beneficial. I'm curious if there is some sort of internal static analysis being conducted that stores this information. Is there a method for acces ...

The argument represented by 'T' does not align with the parameter represented by 'number' and therefore cannot be assigned

I am confused as to why, in my situation, <T> is considered a number but cannot be assigned to a parameter of type number. Changing the type of n to either number or any resolves the issue. Error: Code: const dropFoo = <T>(arr: T[], n: T): T ...

Apply a CSS class once a TypeScript function evaluates to true

Is it possible to automatically apply a specific CSS class to my Div based on the return value of a function? <div class="{{doubleClick === true ? 'cell-select' : 'cell-deselect'}}"></div> The doubleClick function will ret ...

Sharing a Promise between Two Service Calls within Angular

Currently, I am making a service call to the backend to save an object and expecting a number to be returned via a promise. Here is how the call looks: saveTcTemplate(item: ITermsConditionsTemplate): ng.IPromise<number> { item.modifiedDa ...

What is the best way to retry an action stream observable in Angular/RxJS after it fails?

Kindly disregard the variable names and formatting alterations I've made. I've been attempting to incorporate RxJS error handling for an observable that triggers an action (user click) and then sends the request object from our form to execute a ...

Changing states in Ionic Nav View triggers a controller change, however, the view remains the same

Having some trouble with routing in Ionic and Ui-Router. I'm noticing that when I click on the link to change the view (using an anchor tag with ui-sref), the controller changes as expected (I can see output in the console), but the view remains uncha ...

Availability of variables and declaration of functions

I'm having trouble accessing a variable in my Angular project. I am new to this, so please bear with me. Here's an overview of my project: app.component.html: <div> <ul> <li *ngFor='let var1 of Fcomponent' >{{var1}} ...

How to efficiently display nested object data using Angular Keyvalue pipe

I am facing an issue with a particular HTTP request that returns an observable object containing multiple properties. One of these properties is the 'weight' object which has two key values, imperial and metric. While attempting to loop through ...

The issue arises when the desired image size is not reflected correctly on the background after changing

I've been working on a basic image slideshow where the background image changes based on user selection. However, I've noticed that when I change the image for the first time, the backgroundSize: cover property seems to disappear. Even if I try c ...

Organizing objects into arrays in Node.js

I have an array and I need to concatenate an object after the array. Here is my array: const users = [ {name: "Joe", age: 22}, {name: "Kevin", age: 24}, {name: "Peter", age: 21} ] And here is my object: ...

The Order ID field in the Serenity-Platform's Order Details tab is not registering orders

I've been working on replicating the functionality of Orders-Order detail in my own project. https://i.stack.imgur.com/Bt47B.png My custom module is called Contract and Contract Line item, which I'm using to achieve this. https://i.stack.imgur ...

Can we rely on the security of Ionic 4 secure storage encryption?

I'm currently developing an application that necessitates the user to be in close proximity to a specific GPS location. At present, I am obtaining their location every 30 seconds, transmitting it to my server, checking if they are near the desired loc ...

Tips for transforming alphanumeric characters into value ranges using Typescript

myArray = ["AB01","AB02","AB03","AB04","AB11","BC12","BC13", "SB33"]; // code snippet to create expected string: "AB01-AB04, AB11, BC12-BC13, SB33" The array contains combinations of one or two letter characters followed by two or three digits. Examples ...

Incorporate the Input() component into your codebase and take advantage of its dot notation features, such as

Many Angular directives utilize dot notation options: style.padding.px style.padding.% attr.src In addition, libraries like flex-layout employ this for various responsive sizes: fxLayout.gt-sm fxAlign.sm Can the same concept be applied to a component&a ...

What is the rationale behind placing the CSS outside of the React function components, near the imports?

Recently, I encountered an issue with loading CSS inside a React function component using Material UI. Even though I managed to resolve it, I am still intrigued by the underlying reason. Initially, I had something like this setup where I placed both makeSt ...