Skip to content
This repository has been archived by the owner on Nov 17, 2017. It is now read-only.

Commit

Permalink
Merge pull request #2 from YoruNoHikage/master
Browse files Browse the repository at this point in the history
Fix interdependency issue
  • Loading branch information
gpbl committed Apr 5, 2016
2 parents df6ca01 + b2bb4bd commit 81df076
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 19 deletions.
61 changes: 42 additions & 19 deletions src/index.js
Expand Up @@ -3,15 +3,46 @@ import EntitySchema from 'normalizr/lib/EntitySchema';
import UnionSchema from 'normalizr/lib/UnionSchema';
import merge from "lodash/merge";

export function denormalize(entity, entities, entitySchema) {
const denormalized = {};
function getItem(id, key, schema, entities, bag) {
if(!bag[key]) {
bag[key] = {};
}

if(!bag[key][id]) {
bag[key][id] = denormalize(entities[key][id], entities, schema, bag);
}

return bag[key][id];
}

function denormalizeArray(items, entities, schema, bag) {
const itemSchema = schema.getItemSchema();
const itemKey = itemSchema.getKey();
return items.map(id => getItem(id, itemKey, itemSchema, entities, bag));
}

function denormalizeUnion(entity, entities, schema, bag) {
const itemSchema = schema.getItemSchema();
return denormalize(
Object.assign({}, entity, { [entity.schema]: entity.id }),
entities,
itemSchema,
bag
)[entity.schema];
}

export function denormalize(entity, entities, entitySchema, bag = {}) {
const denormalized = merge({}, entity);
if (entitySchema instanceof UnionSchema) {
return denormalize(
Object.assign({}, entity, { [entity.schema]: entity.id }),
entities,
entitySchema.getItemSchema()
)[entity.schema];
return denormalizeUnion(entity, entities, entitySchema, bag);
}

if (entitySchema instanceof EntitySchema) {
const key = entitySchema.getKey();
const id = denormalized[entitySchema.getIdAttribute()];
bag[key] = Object.assign(bag[key] || {}, {[id]: denormalized});
}

Object.keys(entitySchema)
.filter(attribute => attribute.substring(0, 1) !== "_")
.filter(attribute => !!entity[attribute])
Expand All @@ -20,22 +51,14 @@ export function denormalize(entity, entities, entitySchema) {
const itemId = entity[attribute];

if (entitySchema[attribute] instanceof ArraySchema) {
const itemSchema = entitySchema[attribute].getItemSchema();
const itemKey = itemSchema.getKey();
denormalized[attribute] = itemId.map(id => {
const item = entities[itemKey][id];
return denormalize(item, entities, itemSchema);
});
}

if (entitySchema[attribute] instanceof EntitySchema) {
denormalized[attribute] = denormalizeArray(itemId, entities, entitySchema[attribute], bag);
} else if (entitySchema[attribute] instanceof EntitySchema) {
const itemSchema = entitySchema[attribute];
const itemKey = itemSchema.getKey();
const item = entities[itemKey][itemId];
denormalized[attribute] = denormalize(item, entities, itemSchema);
denormalized[attribute] = getItem(itemId, itemKey, itemSchema, entities, bag);
}

});

return merge({}, entity, denormalized);
return denormalized;
}
37 changes: 37 additions & 0 deletions test/index.js
Expand Up @@ -66,6 +66,43 @@ describe("denormalize", () => {

});

describe("parsing interdependents objects", () => {
const articleSchema = new Schema('articles');
const userSchema = new Schema('users');

articleSchema.define({
author: userSchema,
});

userSchema.define({
articles: arrayOf(articleSchema),
});

const response = {
articles: [{
id: 80,
title: 'Some Article',
author: {
id: 1,
name: 'Dan',
articles: [80],
}
}]
};

const data = normalize(response, {
articles: arrayOf(articleSchema)
});

it("should handle recursion for interdependency", () => {
const article = data.entities.articles["80"];
const denormalized = denormalize(article, data.entities, articleSchema);

expect(denormalized.author.articles[0]).to.be.eql(denormalized);
});

});

describe("parsing union schemas", () => {

const postSchema = new Schema('posts');
Expand Down

0 comments on commit 81df076

Please sign in to comment.