Combining Bazel, Angular, and SocketIO Led to: Unforeseen Error - XMLHttpRequest Not Recognized as Constructor

I am looking to integrate ngx-socket-io into my Angular application. I utilize Bazel for running my Angular dev-server. Unfortunately, it seems that ngx-socket-io does not function properly with the ts_devserver by default. Upon checking the browser console, I encountered the following error:

Uncaught TypeError: XMLHttpRequest is not a constructor
    at ts_scripts.js?v=1587802098203:16776
    at Object.23.../transport (ts_scripts.js?v=1587802098203:16780)
    at o (ts_scripts.js?v=1587802098203:11783)

This issue appears to be related to xmlhttprequest-ssl, which is a dependency of engine.io-client and is required by ngx-socket-io. However, this problem specifically arises when using the ts_devserver. Operating the Angular app in production mode works perfectly fine.

Minimal Reproduction

To replicate the issue, you can follow these steps: https://github.com/flolu/bazel-socketio-issue

Simply run yarn install followed by yarn dev (this will trigger the error in the browser console @ http://localhost:4200). Additionally, please note that running yarn prod @ http://localhost:8080 functions without any issues!

Edit 1

There currently appears to be an additional complication on Windows. Therefore, the example repository can only be tested on Mac or Linux systems.

Answer №1

The issue originates from the utilization of engine.io-client within socket.io-client:

During the build process of socket.io-client as a UMD module triggered by:

"@npm//socket.io-client:socket.io-client__umd",

in the BUILD.bazel file, the browser key in engine.io-client/package.json:

"browser": {
   "ws": false,
   "xmlhttprequest-ssl": "./lib/xmlhttprequest.js"
},

appears to be disregarded.

Consequently, the require('xmlhttprequest-ssl') statements in

node_modules/engine.io-client/lib/transports/*.js
persist in the UMD build. Since xmlhttprequest-ssl is designed for headless Node environments and not compatible with browsers, an error occurs.

No definitive cause/issue explanation was found; however, a resolution was discovered (not to be viewed as a temporary fix):

Rework engine.io-client with a postinstall script:

  1. install the shelljs package: yarn add -D shelljs
  2. update the postinstall section in package.json to:
    "postinstall": "node --preserve-symlinks --preserve-symlinks-main ./postinstall-patches.js && ngcc"
  3. insert the provided code into postinstall-patches.js at the project root:
try {
  require.resolve('shelljs');
} catch (e) {
  ...
});

const {set, cd, sed, ls} = require('shelljs');
const path = require('path');
const log = console.info;

...

(Source: , referencing the example at https://github.com/angular/angular/blob/master/tools/postinstall-patches.js)

  1. yarn install
  2. yarn dev

I will soon create a pull request for your GitHub repository.


Potential alternatives that were unsuccessful:

  • utilize
    socket.io-client/dist/socket.io.js
    along with an extra "UMD shim" due to it being an "anonymous UMD" module, OR
  • experiment with some npm_umd_bundle techniques

Refer to issue Every new npm dep needs a unique approach how to add it to ts_devserver #1055 on bazelbuild/rules_nodejs for more insights on both methods.

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

Obtain information from a JSON file based on a specific field in Angular

The structure of the JSON file is as follows: localjson.json { "Product" :{ "data" : [ { "itemID" : "1" , "name" : "Apple" , "qty" : "3" }, { "itemID" : "2" , "name" : "Banana" , "qty" : "10" } ] ...

The Output() function seems to be failing to emit the event

My architecture setup is as follows: UiControlsModule |- Component 1 |- Component 2 The first module is imported and exported in SharedModule. CasesModule |- CaseListComponent |- // other components here SharedModule is also imported into CasesModule. ...

Change values within nested observables

fetchingData() { return this.http.get(environment.remoteUrl + '/client').pipe(pluck('rows'), map((item: any) => item.doc)); } The data is structured like this: { rows: [ {x: 123, doc: {a: 2}}, {x:222, doc: {a: ...

Update the component to display the latest information from the Bryntum grid table

In the Vue component, I have integrated a Bryntum grid table along with a bar chart. Clicking on one of the bars in the chart should update the data displayed in the Bryntum grid table. However, I've encountered difficulty in reloading the entire Bryn ...

The output of switchMap inner will generate an array similar to what forkJoin produces

I have a series of observables that need to run sequentially, with each result depending on the previous one. However, I also need all the intermediate results in an array at the end, similar to what is achieved with the use of forkJoin. Below is the curr ...

Tips for combining HttpClient's Observables with paramMap to create a dynamically loading component

I am currently working with an HTTPClient 'get' method that returns a JSON array of objects. I also utilize a key from the route params to extract a single object from that array. One interesting aspect of this component is its dynamic nature, w ...

Using the useRef validation can lead to errors when trying to reference the current value against an input

Currently, the code is functioning well but an error alert from Typescript needs to be addressed. A warning pops up regarding the use of ref.current.value. ERROR 1. TS18048: 'ref.current' is possibly 'undefined'. To tackle this issue, ...

A function in Typescript that dynamically determines its return type based on a specified generic parameter

Currently, I am attempting to create a function where the return type is determined by a generic argument. Let me share a code snippet to illustrate: type ABCDE = 'a' | 'b'; function newFunc<U extends ABCDE>(input: U): U extends ...

Angular and Ngrx: The optimal approach for choosing a value within a component and a function

While browsing through this Stack Overflow thread, I stumbled upon a question similar to mine. However, I'm curious if the solution provided in the comments is still considered the best practice in today's standards. Here's where I stand: ...

What is the most effective method of utilizing union or extend in TypeScript when faced with a comparable scenario?

I have a function that takes in two different types of objects: const canBeGenericOrDefaultData = { id: 123, pointData: { square: 'x145', triangle: 'y145' } } function submitHandler(canBeGenericOrDefaultData: AllTheDatas | G ...

Testing the Express API with MongoDB on a local machine is successful but encounters a timeout issue on CircleCI

I am facing an issue with testing a RESTful API (built with Express in TypeScript) using Jest. The test passes successfully on my local Windows machine but times out on CircleCI. .circleci/config.ylm version: 2.1 jobs: build: docker: - image: ...

What is the best approach to incorporate Column Reordering in react-data-grid?

Within my REACT application, I have incorporated the npm package react-data-grid. They offer a sample showcasing Column Reordering on their website. I wish to replicate this functionality in my own code. Upon reviewing their source code, I am puzzled abou ...

Angular OpenID: Ensure user authentication before rendering application in web browser

Currently working with Angular 12 and utilizing angular-oauth2-oidc. Authentication has been set up successfully, but there is a brief moment where the application loads before redirecting to the login page. Is there a method to completely hide the app u ...

Using an object-key value array with *ngFor in Angular 7

I am trying to populate an array of objects in a table, but the changes are not being displayed as expected. <ng-container *ngFor="let file of err_data "> <tr> <td>{{file.details.commodity_name}}</td> <t ...

"Building a tree structure from a one-dimensional array in Angular: A step-by-step

I would like to implement a tree structure in Angular using flat array data and I am willing to explore different packages for rendering the tree. Users should be able to click on a node to view details such as node ID and title. The tree should initially ...

TypeError: Unable to access the 'classify' property of an object that has not been defined (please save the ml5.js model first)

In my React app, I have set up ml5.js to train a model by clicking on one button and make predictions with another. However, I encounter an error when trying to test the model for the second time: TypeError: Cannot read property 'classify' of und ...

FirebaseError: Trigger parsing error: Module 'grpc' not found

I'm currently working on setting up an Angular4 application with Server Side Rendering (SSR) using Angular Universal and Firebase Cloud Functions. While the application works smoothly with ng serve, I encountered an issue after building the app and s ...

Tips for dynamically incorporating filtered selections into a Mat-Select dropdown

I am seeking guidance on how to prevent changing the values of already selected values in other rows when each row of the formArray is altered. Adding controls dynamically and correctly retrieving values in filters are functioning properly. The issue arise ...

Will adding a pipe to my code cause a delay in the loading of components?

Visual Representation of Components without Using Pipes Showing a Delay of 1300 milliseconds Illustration of Components Utilizing Pipes with a Delay of 1400 milliseconds ...

Enhancing JavaScript with TypeScript: implementing functional mixins

I'm in the process of creating functional mixins using TypeScript. Below is the code I have written so far: const flying = (o: object) => { let isFlying = false; return Object.assign({}, o, { fly() { isFlying = true; return thi ...