Parsing nested Records in Immutable.js

前端 未结 2 1868
有刺的猬
有刺的猬 2021-02-01 23:01

Suppose I have the following Records defined using Immutable.js:

var Address = Immutable.Record({street: \'\', city: \'\', zip: \'\'});
var User = Immutable.Reco         


        
相关标签:
2条回答
  • 2021-02-01 23:26

    The intended use of Record structure isn't to verify the structure of provided data, just to determine set of keys that are allowed and provide default values if they're not given.

    So using your example, if you initialize the record without providing Address, you will get the proper Immutable.Record object for Address:

    var user = new User({name: 'Foo'});
    // => Record { "name": "Foo", "address": Record { "street": "", "city": "", "zip": "" } }
    

    One hackish way to achieve what you want would be to write a wrapper on Immutable.fromJS method with custom reviver function:

    Immutable.Record.constructor.prototype.fromJS = function(values) {
      var that = this;
      var nested = Immutable.fromJS(values, function(key, value){
        if(that.prototype[key] && that.prototype[key].constructor.prototype instanceof Immutable.Record){return that.prototype[key].constructor.fromJS(value)}
        else { return value }
      });
      return this(nested);
    }
    

    Then you can use it like this:

    var user = User.fromJS({name: 'Foo', address: {street: 'Bar', city: 'Baz'}});
    
    // => User { "name": "Foo", "address": Record { "street": "Bar", "city": "Baz", "zip": "" } }
    

    However if you want to have proper checking your data structures, I would recommend using Immutable.js together with some static type-checker, like http://flowtype.org/ or http://www.typescriptlang.org/

    0 讨论(0)
  • 2021-02-01 23:29

    You can make User subclass the Record definition and parse address in the constructor:

    import {Record} from 'immutable'
    
    const Address = Record({street: '', city: '', zip: ''});
    class User extends Record({name: '', address: new Address()}) {
      constructor({name, address} = {}) {
        super({name, address: new Address(address)})
      }
    }
    
    const user = new User({
      name: 'Andy',
      address: {
        street: 'wherever',
        city: 'Austin',
        zip: 'TX'
      }
    })
    
    console.log(user)
    console.log('user.address instanceof Address:', user.address instanceof Address)
    
    const user2 = new User({name: 'Bob'})
    
    console.log(user2)
    console.log('user2.address instanceof Address:', user2.address instanceof Address)
    

    Output:

    User { "name": "Andy", "address": Record { "street": "wherever", "city": "Austin", "zip": "TX" } }
    user.address instanceof Address: true
    User { "name": "Bob", "address": Record { "street": "", "city": "", "zip": "" } }
    user2.address instanceof Address: true
    
    0 讨论(0)
提交回复
热议问题