Mutating an Immutable.js Record on creation

Posted by

The idea is that you pass a certain structure into the record as it’s loaded from a source, but you want to mutate it into another structure. Obviously you can do this before you pass it into the new Record() call, but if you are re-using a subclass of Record (in my example named Email) then it’s handy to have it happen when creating a new Email.

I needed it to be more than just virtual properties, because I wanted to make changes to it when updates where made on the interface and rather than have a setter and getter for this that processed the input/output and converted it to the structure I wanted, I only needed to do the processing of the data once.

This was my original setup before I needed template settings:

const Immutable = require('immutable');

const Email = Immutable.Record({
  id: '',
  to: '',
  from: '',
  subject: '',
  body: ''
});

module.exports = Email;

Generally the structure of the object I collect from the server is:

{
  id: '12345abcd',
  to: 'email@somewhere.com',
  from: 'sale@store.com',
  subject: 'Hi {{ name }}, you are missing out',
  body: 'Hi {{ name }}, we noticed you left something behind...',
  title: 'Existing Customer',
  segment: 'existing_customer',
  delay: '1',
  rule: 'from_recoverable'
}

In this object title, segment, delay and rule are all part of the template settings. This object is part of a bigger system, and there are slight differences in the object I can receive based on the requirements needed for each type of email.

So to convert this object into the object I need on the client side I do the following:

const Immutable = require('immutable');

const Email = Immutable.Record({
  id: '',
  to: '',
  from: '',
  subject: '',
  body: '',
  templateSettings: {}
});

class EmailRecord extends Email {
  constructor(data) {
    // Create a list of potential settings to look for
    const settingProperties = ['title', 'segment', 'delay', 'rule'];

    // Loop through the settings looking for entries in data
    const templateSettings = {};
    for (const prop in settingsProperties) {
      // If the setting exists pass it into templateSettings
      if (data[prop]) templateSettings[prop] = data[prop];
    }
    data.templateSettings = templateSettings;

    // Go about creating the immutable record
    super(data);
  }
}

module.exports = EmailRecord;

In this example I haven’t bothered removing the excess properties from data because Immutable.js will filter them out using the configuration set above.

I now that a nice clean object like this to play with:

{
  id: '12345abcd',
  to: 'email@somewhere.com',
  from: 'sale@store.com',
  subject: 'Hi {{ name }}, you are missing out',
  body: 'Hi {{ name }}, we noticed you left something behind...',
  templateSettings: {
    title: 'Existing Customer',
    segment: 'existing_customer',
    delay: '1',
    rule: 'from_recoverable'
  }
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s