Establish a connection to the ActiveMQ broker utilizing STOMP protocol in an Ionic application

I've recently received an Ionic + Capacitor app that is primarily meant to run on the Android platform. My current task is to incorporate communication with a remote ActiveMQ broker into the app. To achieve this, I utilized the STOMP JS library which works seamlessly when tested on the browser. However, encountering connectivity issues when testing on the emulator led me to believe that the problem lies in the emulator's inability to understand the WS URL, unlike the browser which supports WebSockets by default. Researching online, I came across using SockJS as a potential simple solution and found a tutorial that may help in integrating it smoothly into my existing code:

Following the instructions provided in the tutorial and adding the fallback code resulted in encountering a strange error thrown by the Typescript compiler. Here is a snippet of my code:

import {Client, Message, ActivationState, messageCallbackType} from '@stomp/stompjs'
//import StompJs, { Message } from '@stomp/stompjs';
import { Queue } from 'queue-typescript';
import SockJS from 'sockjs-client';

const brokerEndpoint = "ws://localhost:61614";
//const brokerEndpoint = "ws://10.0.2.2:61614";

const items: string[] = [];
const queue = new Queue<string>(...items);

const createClient = () => {
    const client: Client = new Client({
        brokerURL: brokerEndpoint,
        connectHeaders: {
            login: 'admin',
            passcode: 'admin',
        },
        debug: function (str) {
            console.log(str);
        },
        reconnectDelay: 1000,
        heartbeatIncoming: 0,
        heartbeatOutgoing: 0
    });

    client.webSocketFactory = new SockJS('http://localhost:61613/stomp');

    /*
    if (typeof WebSocket !== 'function') {
        console.log("Not WebSocket");
        // For SockJS you need to set a factory that creates a new SockJS instance
        // to be used for each (re)connect
        client.webSocketFactory = function () {
            // Note that the URL is different from the WebSocket URL
            return new SockJS('http://10.0.2.2:15674/stomp');
        };
    } else {
        console.log("Still using WebSockets");
    }
    */

    return client;
}

const client: Client = createClient()

The error is triggered at the following line:

client.webSocketFactory = new SockJS('http://localhost:61613/stomp');

The compiler indicates that "Type 'WebSocket' is not assignable to type '() => IStompSocket'. Type 'WebSocket' provides no match for the signature '(): IStompSocket'."

Despite following the tutorial, there appears to be a conflict according to Typescript. Anyone who has experience working with SockJS + STOMP or any of the imported libraries successfully? Any assistance would be highly valued!

Answer №1

I encountered a similar issue to yours, which was caused by the version of the npm dependency @stomp/stompjs.

After some investigation, it appears that the developer who updated it made some changes but ended up creating confusion. They neglected to update the official documentation as well.

On the official website, it still states that the method webSocketFactory returns a WebSocket interface, when in reality, it returns IStompSocket. While these are meant to be similar, they are not interchangeable, and there's no documented way to convert a WebSocket to IStompSocket, leading to the failure.

Here is the solution:

1. Uninstall the current version by typing:

npm uninstall @stomp/stompjs

2. Install the same dependency with this specific version:

npm install @stomp/[email protected] --save

I hope this resolves your issue.

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

NPM Package: Accessing resources from within the package

My Current Setup I have recently developed and published an npm package in typescript. This package contains references to font files located within a folder named public/fonts internally. Now, I am in the process of installing this package into an Angul ...

Function exported as default in Typescript

My current version of TypeScript is 1.6.2 and we compile it to ECMA 5. I am a beginner in TypeScript, so please bear with me. These are the imported library typings. The contents of redux-thunk.d.ts: declare module "redux-thunk" { import { Middle ...

Is it possible to exclude a certain prop from a styled component that has emotions?

Within my code, there exists a component called BoxWithAs, which is defined as follows: const BoxWithAs = styled.div( { WebkitFontSmoothing: 'antialiased', MozOsxFontSmoothing: 'grayscale' // And more … } ); Everythin ...

Is it possible to access the attributes of an interface in TypeScript without relying on external libraries?

Ensuring the properties of an interface align with an object that implements it is crucial for successful unit testing. If modifications are made to the interface, the unit test should fail if it is not updated with the new members. Although I attempted ...

The integration of react-color Saturation with @types/react-color is currently unavailable

In my quest to develop a customized color picker, I am utilizing the react-color library (^2.19.3) together with @types/react-color (^3.0.4). The issue arises when trying to import the Saturation component since it is not exported from the types in the ind ...

Error in Angular: The use of decorators in this context is not allowed.ts(1206)

In my current project using Angular 17 and PrimeNG 17, I am implementing a theme switching feature. I have been following a tutorial from the Primeng documentation at this link: https://www.youtube.com/watch?v=5VOuUdDXRsE&embeds_referring_euri=https%3A ...

Retrieve the value of the specific element I have entered in the ngFor loop

I've hit a wall after trying numerous solutions. Here is the code I'm working with: HTML: import { Component } from '@angular/core'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styl ...

What is causing the reluctance of my Angular test to accept my custom form validation function?

I'm currently facing an issue with testing an angular component called "FooComponent" using Karma/Jasmine. Snippet of code from foo.component.spec.ts file: describe('FooComponent', () => { let component: FooComponent let fixture ...

Updating the alignment between two input mat-select in Angular materialAlternatively:Fine-tuning the reference between

I am currently working on an Angular 6 app: I have two mat-select inputs that I want to connect in a way that if the selected option in my First select is equal to the value 'AAA', then the Second select should be hidden. First Mat-Select -> & ...

What is the process for setting up a subrouter using React Router v6?

This is the current React Router setup I am using: const router = createBrowserRouter([ { path: "/", element: ( <Page activeNav="home" > <Home /> </Page> ) }, { ...

Tips on how to increase and update the index value by 2 within an ngFor loop while maintaining a fixed format

I have a specific template layout that displays only two items in each row as shown below. I want to use the ngFor directive to iterate through them: <div class="row" *ngFor="let item of cityCodes; let i = index"> <div class="col-6" (click)= ...

Listening to changes in a URL using JQuery

Is there a way to detect when the browser URL has been modified? I am facing the following situation: On my webpage, I have an iframe that changes its content and updates the browser's URL through JavaScript when a user interacts with it. However, no ...

How can I make Cesium, SystemJS, and Angular2 compatible with each other?

Could anyone provide a working example of using SystemJS (not Webpack) with Angular2 (in TypeScript, not Dart) and Cesium (npm)? I came across a blog post on cesiumjs' site that discusses this: The author mentioned, "You can't simply do a requi ...

A step-by-step guide on customizing the background color of a Dialog in Angular Material (Version 16)

I've been attempting to modify the background color of my Angular Material Dialog by utilizing the panelClass property in the MatDialogConfig. Unfortunately, I'm encountering a partial success. I am aiming to set the background color as red (jus ...

What prevents me from extending an Express Request Type?

My current code looks like this: import { Request, Response, NextFunction } from 'express'; interface IUserRequest extends Request { user: User; } async use(req: IUserRequest, res: Response, next: NextFunction) { const apiKey: string = ...

Error: Unrecognized error encountered while using Angularjs/Ionic: Property 'then' cannot be read as it is undefined

codes: js: angular.module('starter.services', ['ngResource']) .factory('GetMainMenu',['$http','$q','$cacheFactory',function($http,$q,$cacheFactory) { var methodStr = 'JSONP' ...

I want to create a feature where a video will automatically play when a user clicks on a specific item in a list using Angular

Currently, I'm working on a project that involves displaying a list of videos and allowing users to play them in their browser upon clicking. The technology stack being used is Angular 2. Below is the HTML code snippet for achieving this functionalit ...

Are you facing difficulties while trying to utilize useContext in your React application?

I have a basic React application where I need to implement useContext. (by the way, I am using Vite + React) Below is the code for my Context.jsx file: import React, {useContext} from 'react'; const emailContext = React.createContext(); expor ...

Exploring Angular 7: Understanding the HTML5 Fullscreen API and Overcoming Errors

I am currently using Angular 7 and I am trying to implement a fullscreen button in my app. I have utilized the HTML5 Fullscreen API and created two functions for this purpose: openfullscreen() { // Trigger fullscreen console.log('gg'); ...

Issue encountered while generating dynamic Routes using the map function

When attempting to dynamically use Route from an array, I encounter an error. Warning: Incorrect casing is being used. Use PascalCase for React components, or lowercase for HTML elements. The elements I am utilizing are as follows: const steps = [ { ...