reactjsreduximmutable.js

Immutable.js - fromJS generate Record in place of Map


I've been having a play with React, Redux and Immutable and have come across something I really dislike. I have a large JSON data set returned from the server which I'm parsing into Immutable using the fromJS helper.

All well and good, however when it comes to accessing the properties in my Components I'm forced to use the Immutable specific getters and setters. My issue is being bound to Immutable, say along the line I decided to change this I would have to go through each and every Component and adjust accordingly.

Which brings me to my question, currently fromJS returns Lists and Maps, is it possible to replace the Maps with Records?

This would then decouple my Components from Immutable and have native properties, e.g user.name rather than user.get('name').

I've read a little about revivers but can't seem to find a similar use case.

I've had a play with the following but I'm unsure if it's the best solution:

var result = Immutable.fromJS({

    id: 2039428947,
    name: 'James',
    email: 'james@email.com',
    country: 'United Kingdom'

}, function(key, value) {

    var obj = Immutable.Record(value.toJS());

    return new obj(value);

});

Thanks


Solution

  • UPDATED

    I've wrapped this up in a tiny package that can do this for you: https://www.npmjs.com/package/immutable-parsejs

    ORIGINAL ANSWER

    For anyone else who's interested in using ImmutableJS but also having the ability to use native properties in Components, e.g user.name instead of user.get('name'), simply use the below function instead of fromJS:

    function convertJs(js) {
    
       if(typeof js !== 'object' || js === null) {
    
           return js;
    
       }
    
       if(Array.isArray(js)) {
    
           return Seq(js).map(convertJs).toList();
    
       }
    
       let obj = Record(js);
    
       obj = new obj(Seq(js).map(convertJs));
    
       return obj;
    
    }
    

    One thing to keep in mind is property conflicts, make sure that the objects you feed into the function don't contain property names used by ImmutableJs, size is a good example. If there is a conflict you'll get the following message with no indication of where the problem is:

    Uncaught Error: Cannot set on an immutable record