json-model-mapper

0.0.3 • Public • Published

JsonMapper

Small Simple JS Json mapper

Map one json object to another. JS developer life is hard. You're getting numbers as strings. Someone on the backend is returning objects with underscores, so you called the police, but now you're stuck with this server.

Mapping definitions

First simple case, consider this response vrom server:

const resp = {
  "playerId": "123e4567-e89b-12d3-a456-426655440000",
  "numberOfLives": "4",
  "lastRecord": "2018-05-14T03:00:00+0200"
}

Define transformation:

const playerMapping = {
  "playerId": String,
  "numberOfLives": Int,
  "lastRecord": Date
}

Call: mapJson(resp, playerMapping)

And this is the result:

{
  const resp = {
    "playerId": "123e4567-e89b-12d3-a456-426655440000",
    "numberOfLives": 4,
    "lastRecord": new Date("2018-05-14T03:00:00+0200")
  }
}

But now you can do more cool stuff. For example you have another api, returning list of users. Now you can reuse your mapping, on the list:

const listMapping = {
  "userList": new ComplexArray(playerMapping)
}

So when you receive array of users, each object will be mapped correctly to your needs.

But wait there's more.

Key PlayerId sounds little too tedious. So you can define transformation:

const advancedPlayerMapping = {
  "playerId": {
    toName: "id",
    type: String,
  },
  "numberOfLives": Int,
  "lastRecord": Date
}

and now the output will be

const mappedResp = {
  "id": "123e4567-e89b-12d3-a456-426655440000",
  "numberOfLives": 4,
  "lastRecord": new Date("2018-05-14T03:00:00+0200")
}

But wait there's more!

Wha if playerId consists of multiple parts with meaning. First part is groupId. Now you need more complex transformation. For that purpose you can write your own mapping function.

function idMapper(value) {
  const idSplit = value.split("-");
  return {
    groupId: idSplit[0],
    playerId: value,
    isValid: value.includes("-")
  }
}


const playerMapping = {
  "playerId": {
    toName: "playerIdentifier",
    mapper: idMapper,
  },
  "numberOfLives": Int,
  "lastRecord": Date
}

Now the result will be:

const mappedResp = {
  "playerIdentifier": {
    groupId: "123e4567",
    playerId: "123e4567-e89b-12d3-a456-426655440000",
    isValid: true,
  },
  "numberOfLives": 4,
  "lastRecord": new Date("2018-05-14T03:00:00+0200")
}

Mapping configuration

Defining these mapping objects can do for you more than you expect. You can for example force consistency of object structures. There is third argument to function: mapJson(obj, mappingDef, options)

options = {
  includeUndescribed: boolean, // includes also attributes not specified in mappingDef
  fillMissing: boolean, // add missing keys from obj - default true
}

So having input object

const simpleObj = {
  attr1: "string1",
  attr2: "string1",
  attr3: "string1",
}

and mapping definition:

const simpleMapping = {
  attr1: String,
  attr3: String,  
  attr4: String,  
}

calling const mappingResult = mapJson(simpleObj, simpleMapping) will produce

const mappingResult = {
  attr1: "string1",
  attr3: "string1",
  attr4: null,
}

thus maintaining the structure defined in simpleMapping.

Or define your custom default value for attributes

const simpleMapping = {
  attr1: String,
  attr3: String,  
  attr4: {
    type: String,
    defaultValue: "this is missing string"
  },  
}

with result

const mappingResult = {
  attr1: "string1",
  attr3: "string1",
  attr4: "this is missing string",
}

For more information consult TypeMapper.js.flow with comments and all options.

That's all folks;

Readme

Keywords

none

Package Sidebar

Install

npm i json-model-mapper

Weekly Downloads

1

Version

0.0.3

License

MIT

Unpacked Size

19 kB

Total Files

11

Last publish

Collaborators

  • kvimbi