Search code examples
javascriptimmutabilityimmutable.jsreviver-function

How to create a map of records from a javascript raw object with Immutable.js?


I'm new to immutable.js and I'd like to understand better how to use records starting from a raw JS object.

With Immutable.fromJS() I can create a map passing a raw object, for example:

var images = {
   "1": {
    id: "1",
    urls: ["/medium/1.jpg", "/large/1.jpg"]
   },
   "2": {
    id: "2",
    urls: ["/medium/1.jpg", "/large/1.jpg"]
   }
  }

var imagesMap = Immutable.fromJS(images);

imagesMap is now a map containing other maps, one for each image.

I'd like instead to create a map containing records, for example using a Image record defined as:

var ImageRecord = Immutable.Record({ id: undefined, urls: undefined })

How can I have imagesMap as map of ImageRecords? Is something I can do passing a reviver to fromJS, or should I go with the "old" approach?

// old approach
var imagesMap = Immutable.Map()
for (key in images) {
   imagesMap.set(key, new ImageRecord(images[key]))
}

Solution

  • Immutable.fromJS has an optional second parameter reviver that you can use. You just need to decide which parts of the js object you want to turn into records.

    var images = {
       "1": {
        id: "1",
        urls: ["/medium/1.jpg", "/large/1.jpg"]
       },
       "2": {
        id: "2",
        urls: ["/medium/1.jpg", "/large/1.jpg"]
       }
      };
    
    var ImageRecord = Immutable.Record({ id: "0", urls: [] })
    
    var imagesMap = Immutable.fromJS(images, function(key, value) {
      // This check should be replaced by a better way to know that
      // we really want image records
      if(/^[0-9]+$/.test(key)) {
        return new ImageRecord(value)
      }
      return value
    });
    
    // Verify that it's really a record
    console.log(imagesMap.get("2").toJS())
    console.log(imagesMap.get("2").delete("urls").toJS())
    

    http://jsbin.com/ronomibano/4/edit