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

Unit testing of an expired JWT token fails due to the incorrect setting of the "options.expiresIn" parameter, as the payload already contains an "exp" property

I am having trouble generating an expired JWT token for testing purposes and need some guidance on how to approach it. How do you handle expiration times in unit tests? This is what I have attempted so far : it('should return a new token if expired& ...

Rearranging items within an array in a React component

Currently, I am facing a situation where I have created a list that dynamically adds a React Node upon clicking a button. The final layout of the model looks like this: Here is the code snippet for your reference: import * as React from 'react' ...

Using Angular 6's httpClient to securely post data with credentials

I am currently working with a piece of code that is responsible for posting data in order to create a new data record. This code resides within a service: Take a look at the snippet below: import { Injectable } from '@angular/core'; import { H ...

Update the registerForm input from a boolean value to a number

Confused about how to convert a boolean to a number Issue : I'm struggling trying to convert my registerForm.value.aleas, which is a checkbox, into a number (0 for false, 1 for true) in order to perform a POST request (the API expects values of eith ...

The issue lies with the Cookies.get function, as the Typescript narrowing feature does not

Struggling with types in TypeScript while trying to parse a cookie item using js-cookie: // the item 'number' contains a javascript number (ex:5) let n:number if(typeof Cookies.get('number')!== 'undefined'){ n = JSON.pars ...

What method can be used to specify a function of any signature that returns a particular type in programming?

I am looking to define a unique type that must be a function which, when executed, will always produce an object containing the property type: string. The input parameters for this function are of no concern. For instance: foo(1, 'bar'); // res ...

I experienced an issue with Firestore where updating just one data field in a document caused all the other data to be wiped out and replaced with empty Strings

When updating data in my Firestore document, I find myself inputting each individual piece of data. If I try to edit the tag number, it ends up overwriting the contract number with an empty string, and vice versa. This issue seems to stem from the way th ...

Refreshing Angular 4 route upon modification of path parameter

I have been struggling to make the subscribe function for the params observable work in my Angular project. While I have successfully implemented router.events, I can't seem to get the subscription for params observable working. Can anyone point out w ...

Issue: Angular 14 - Validators Not Resetting in Nested FormGroup

I am currently working on implementing a nested FormGroup. However, I have encountered an error when attempting to reset the form. Here is the structure of the form: form: UntypedFormGroup; this.form = this.fb.nonNullable.group({ f1: [''], f2: ...

Firefox unable to detect click events

I am facing an issue with my Angular 2 website where it is not functioning correctly in Firefox. The main problem lies in the fact that Firefox does not recognize the event being passed into my TypeScript function. This event specifically pertains to a mou ...

Learn how to transfer information via WebSocket when the connection closes in a React/NextJS application during a page reload or tab

In the development of my web application, I am implementing a feature to display the online/offline status of users. In order to achieve this functionality, I have to listen for both close and open events of the websocket. const ws = new WebSocket('ws ...

Toggle the Visibility of your Password

I am currently working on implementing a TypeScript function in my webpage to enable the toggling of password visibility using an icon. The desired functionality is as follows: when a button (in this case, a clickable icon) is pressed, the icon should chan ...

Using React MUI Select in combination with react-hook-form does not seem to be compatible with Cypress testing

Within my React application, I have implemented a form that includes a dropdown select. Depending on the option selected from the dropdown, different input fields are rendered. const [templateType, setTemplateType] = useState(""); const { regi ...

Is there a way to navigate to a specific component selector within an ngFor loop?

I have a scenario where I have multiple components running inside *ngFor on the same page. My goal is to create button links at the top of the page that, when clicked, will scroll to the corresponding component on the page. Below are the code snippets tha ...

Error in Typescript: Array containing numbers is missing index property `0`

This is the code for my class: class Point{ coordinates: [number, number, number]; constructor(coordinates: [string, string, string]) { this.coordinates = coordinates.map((coordinate) => { return Math.round(parseFloat(coordinate) *100)/ ...

Instructions for adding a new property dynamically when updating the draft using immer

When looking at the code snippet below, we encounter an error on line 2 stating Property 'newProperty' does not exist on type 'WritableDraft<MyObject>'. TS7053 // data is of type MyObject which until now has only a property myNum ...

Difficulty with Angular's Interpolation and incorporating elements

I've encountered an issue with String Interpolation while following an Angular course. In my server.component.ts file, I've implemented the same code as shown by the teacher in the course: import { Component } from "@angular/core"; @Component ( ...

Please place the accurate image inside the designated box based on the corresponding ID number

I am currently working on a function that retrieves image data from a database and displays it in HTML using *ngFor directive. In order to display the correct image, I need to fetch the ID associated with the image data and use it to retrieve the correspo ...

Ensuring Mongoose Schema complies with an external API

My database schema includes a mongoose User schema with the following structure: const User: Schema = new Schema({ // some other fields email: {type: String, unique: true, require: true, validate: [myValidator, 'invalid email provided'], // some ...

Ways to achieve outcomes from functions employing concatMap within rxjs?

When calling two functions, I make use of fn1 and fn2. To execute them one after the other, I utilize concatMap. I choose not to use exhaustMap and switchMap as they can result in nested "callback-hell". exhaustMap(() => fn1().pipe( swit ...