Skip to content

Instantly share code, notes, and snippets.

@zuk
Last active February 3, 2016 10:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zuk/4ac39e30381d77ade2e6 to your computer and use it in GitHub Desktop.
Save zuk/4ac39e30381d77ade2e6 to your computer and use it in GitHub Desktop.
Denormalizr
// copied from https://github.com/dotcs/normalizr/blob/963f9297ef5c97866bc3e6de5cdef730155a3e09/src/index.js
// ... waiting until this gets merged into normalizr
// see https://github.com/gaearon/normalizr/pull/20
import isObject from 'lodash/lang/isObject'
import clone from 'lodash/lang/clone'
import { Schema as EntitySchema } from 'normalizr'
function visitObjectForDenorm(obj, schema, bag) {
var denormalized = {},
key = Object.keys(obj)[0]
denormalized[key] = visitForDenorm(obj[key], schema[key], bag)
return denormalized
}
function visitArrayForDenorm(obj, arraySchema, bag) {
var itemSchema = arraySchema.getItemSchema(),
itemSchemaKey = itemSchema.getKey(),
denormalized
var item = clone(bag[itemSchemaKey])
denormalized = []
obj.forEach(function(itemKey) {
var keys
if (item.hasOwnProperty(itemSchemaKey)) {
denormalized.push(visitForDenorm(item[itemKey], itemSchema[itemSchemaKey], bag))
} else {
keys = Object.keys(itemSchema)
if (keys.length <= 2) {
denormalized.push(visitForDenorm(item[itemKey], undefined))
} else {
denormalized.push(visitForDenorm(itemKey, itemSchema, bag))
}
}
})
return denormalized
}
function visitEntityForDenorm(entity, entitySchema, bag) {
var entityKey = entitySchema.getKey()
var denormalized = clone(bag[entityKey][entity])
Object.keys(entitySchema).forEach(function(schemaKey) {
if (schemaKey.indexOf('_') !== 0) { // TODO: better way to access the relevant schema keys?
if (typeof denormalized === 'object' && denormalized.hasOwnProperty(schemaKey)) {
denormalized[schemaKey] = visitForDenorm(denormalized[schemaKey], entitySchema[schemaKey], bag)
}
}
})
return denormalized
}
function visitForDenorm(obj, schema, bag) {
if (!isObject(schema)) {
return obj
}
if (schema instanceof EntitySchema) {
return visitEntityForDenorm(obj, schema, bag)
} else if (obj instanceof Array) { // hack because normalizr doesn't export ArraySchema
return visitArrayForDenorm(obj, schema, bag)
} else {
return visitObjectForDenorm(obj, schema, bag)
}
}
export function denormalize(obj, schema) {
if (!isObject(obj) && !Array.isArray(obj)) {
throw new Error('Denormalize accepts an object or an array as its input.')
}
if (!isObject(schema) || Array.isArray(schema)) {
throw new Error('Normalize accepts an object for schema.')
}
var bag = obj.entities
var result = obj.result
var denormalized = visitForDenorm(result, schema, bag)
return denormalized
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment