Is it necessary for me to disregard the notion of global module state when utilizing Immutable JS?

Recently, I came across Immutable JS and was intrigued by its potential to reduce bugs caused by accidental mutations. The library also offers performance optimizations, but I'm struggling to grasp how to manage state within a module.

For instance, in a scenario where I have a socket.io server supporting multiple streams, I typically use two global variables within the module to track connected clients and available streams:

var clients = []
var streams = []

If a user connects, I can easily update the client state using .push in the io.on("connection") event handler knowing that the new socket is added.

With Immutable JS, my module's object structure now looks like this:

var state = Immutable.Map({
    clients : Immutable.List.of(),
    streams : Immutable.List.of()
})

But inside the socket io connection handler, I'm unsure about updating the global state. It seems challenging to maintain application state with Immutable JS as I currently understand it.

// Define the Immutable array, remains constant throughout the application
var state = Immutable.Map({
    clients : Immutable.List.of(),
    streams : Immutable.List.of()
})

io.on("connection", (socket) => {

     console.log(state.clients)    

     // Attempting to update the state of clients here leads to issues 
     // as changes are local within the current scope

     var clientsArray = state.clients
     clientsArray.push(socket)
     state.set("clients", clientsArray)

     console.log(state.clients)
})

Based on my understanding, I anticipate the following output when two clients connect:

// First client connects
[]
[ { socket object } ]

// Second client connects
[]
[ { socket object } ]

Is there a way to update the object to achieve this instead?

[ { socket object }, { socket object } ]

Or should I resort to using mutable global state? This dilemma arises because methods in React allow updating component state and using the new state elsewhere in the component.

Answer №1

Your code is missing a straightforward assignment step. Since you are using immutable, any update operation such as set, will result in a new object being created instead of modifying the existing one. For your specific case, calling

state.set("clients", clientsArray)
does not actually alter the global state; it simply returns a fresh instance with the modified clients List. To resolve this issue, you simply need to update the global state with the outcome of the method call like this -

state = state.set("clients", clientsArray);

Alternatively, you could condense this process into one line like so -

state = state.set("clients", state.get("clients").push(socket));

I hope this clarifies things for you!

Remember that it's essential to have an assignment statement whenever invoking a method that alters or mutates an immutable object.

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

"How can I make a dropdown open and close when a button is clicked, but also close when clicking outside of it at the same

One button click opens a dropdown, and it also closes when clicked outside. toggleAllCategories() { this.setState({ isOpenAllCategories: !this.state.isOpenAllCategories }); } The issue arises when attempting to open and close the dropdown by clic ...

Creating unique reusable Angular components with dynamic attributes similar to React's props

I am looking to create a custom component that will allow me to insert content inside the opening and closing tags, which will be placed exactly where I want it within my HTML code. Here is an example of what I am trying to achieve: <my-custom-compo ...

Sorting in Postgres is about organizing data in a specific order

I've been working on organizing my Postgres questions database by ID. Currently, the order seems random, but I want it to be sorted by ID in ascending order. Since I'm new to Postgres, I'm not entirely sure about what I need to do... All ...

Cannot assign type void to 'Intrinsic Attributes & Dispatch<SetStateAction<>>'

Just starting out with typescript and ran into this error: Error :Type '{ setTasks: void; }' is not assignable to type 'IntrinsicAttributes & Dispatch<SetStateAction<IStudy[]>>'. Property 'setTasks' does not e ...

Are there any advantages to using arrays with non-contiguous indices that outweigh their drawbacks?

When working with JavaScript arrays, it's important to note that arrays can have gaps in their indices, which should not be confused with elements that are simply undefined: var a = new Array(1), i; a.push(1, undefined); for (i = 0; i < a.length; ...

Sort the array and organize it by frequency

Given the input array: array = [ 1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20 ] The expected output is: [ [ 1, 1, 1, 1 ], [ 2, 2, 2 ], 4, 5, 10, [ 20, 20 ], 391, 392, 591 ] Using the following function to generate the result: var array = [ ...

Unable to convert data to a JSON string

I've created a tool for building dynamic tables: <div class="container"> <div class="row"> <div class="col"> <hr> <h3>Add your data</h3> <button id="addTd" type="button" class="btn btn-pr ...

Tips for grouping radio buttons that span multiple rows within an ag-grid

I am currently working on a grid layout that consists of multiple rows, with each row containing a radio button as illustrated in the snapshot below: https://i.sstatic.net/O8i0r.png Here is the code snippet for the column definition of the radio button: ...

Execute a query in Firestore with a "where" filter

I am trying to filter and retrieve specific items based on the categoryID using the "where" method and the "==" operator. In my Firestore collection named "task", each user has a document with an array of different tasks. Here is the structure: Click here ...

Tips for sending multiple pieces of data to an Arduino with NodeJS's serialport library

I am having trouble writing multiple data using the same port, but I see that node-serialport allows for reading multiple data functions simultaneously. How can I also write multiple data at the same time? This is how I have attempted it: - index.js- con ...

Is the connection still open post test completion?

I have a straightforward postgres.js wrapper file. const pg = require("pg") const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL }); function shutDown() { return pool.end() } module.exports = { end: pool.end, close: shutDown ...

Having difficulty entering text into the Material UI TextField

I am encountering an issue with a button that opens up a Material UI Dialog containing a TextField. However, I am unable to click into the TextField to input any text. Additionally, when clicking on the button to open the Dialog, I receive the error messag ...

Mastering the Art of Crafting an Effortless Slide Showcase

I have created a carousel that works fine except for one issue: when I reach the last image or go back from the first image, I want the image to be displayed. For example, when you click the right arrow after reaching the last image, it should show the fir ...

Exclude unresolved Promises

I have a collection of Promise instances that I would like to iterate through in order to identify and remove the rejected Promises. Desired outcome: const promises = [ failedPromise, successPromise, successPromise, ]; const resolvedPromises = pro ...

Transitioning from a fixed position to absolute in CSS3

Sticky Logo Element In my project, I implemented a logo element that is positioned absolutely within the document. As the user scrolls, the logo sticks to the top of the window with a fixed position (you can view an example here: https://jsfiddle.net/swzb ...

Submit an Ajax form to process data in PHP upon selecting a radio button

I am troubleshooting an issue with a form that is not submitting data to processor.php for processing and storing responses in a database. Ensuring that the form submission does not cause a page refresh is crucial, as there is an iframe below the form tha ...

Assistance for Hypertext Transfer Protocol in Webkit

I've been researching how webkit enables web browsers to display web pages. It's great to know that my HTML, CSS, and JavaScript code will work on any device that supports webkit. But one question still remains - does webkit also have built-in su ...

Upgrade jQuery visibility and opacity animations to pure JavaScript for a more lightweight solution

Currently I am in the process of removing jQuery from an older website. However, I have encountered a problem with an animation that is currently being used. I have managed to replicate the opacity fade effect, but I am struggling to smoothly transition t ...

Modifying the value of a React input component is restricted when the "value" field is utilized

I'm currently utilizing material-UI in my React application. I am facing a challenge where I need to remove the value in an input field by clicking on another component. The issue arises when using the OutlinedInput component with a specified value. ...

Customizing AxiosRequestConfig with Axios in TypeScript can greatly enhance the functionality and

Currently working with React and Axios. Lately, I've been experimenting with custom configurations in Axios as shown below: import $axios from 'helpers/axiosInstance' $axios.get('/customers', { handlerEnabled: false }) However, wh ...