Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/gpbl/denormalizr
Denormalize data normalized with normalizr
https://github.com/gpbl/denormalizr
data-structure flux normalizr redux
Last synced: 3 months ago
JSON representation
Denormalize data normalized with normalizr
- Host: GitHub
- URL: https://github.com/gpbl/denormalizr
- Owner: gpbl
- License: mit
- Archived: true
- Created: 2016-03-20T20:31:07.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2017-06-12T14:41:51.000Z (over 7 years ago)
- Last Synced: 2024-08-01T19:45:30.099Z (6 months ago)
- Topics: data-structure, flux, normalizr, redux
- Language: JavaScript
- Homepage: https://www.npmjs.com/package/denormalizr
- Size: 208 KB
- Stars: 228
- Watchers: 5
- Forks: 24
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
## Deprecated
⚠️ This package [is deprecated](https://github.com/gpbl/denormalizr/issues/39). Please use normalizr's built-in [`denormalize()`](https://github.com/paularmstrong/normalizr/blob/master/docs/api.md#denormalizeinput-schema-entities), thanks!
---
**denormalizr** takes data and entities normalized by [normalizr](https://github.com/gaearon/normalizr), and returns its complete tree – including nested entities.
This module is useful when consuming normalized data, e.g. in redux [selectors](http://redux.js.org/docs/recipes/ComputingDerivedData.html). While normalizr is great on making data consistent between the app, reassembling entities can be a tedious work. Denormalizr can help!
[![npm version](https://img.shields.io/npm/v/denormalizr.svg?style=flat-square)](https://www.npmjs.com/package/denormalizr)
[![npm downloads](https://img.shields.io/npm/dm/denormalizr.svg?style=flat-square)](https://www.npmjs.com/package/denormalizr)
[![build status](https://img.shields.io/travis/gpbl/denormalizr/master.svg?style=flat-square)](https://travis-ci.org/gpbl/denormalizr)
[![Code Climate](https://img.shields.io/codeclimate/github/gpbl/denormalizr.svg?style=flat-square)](https://codeclimate.com/github/gpbl/denormalizr)
[![Coveralls](https://img.shields.io/coveralls/gpbl/denormalizr.svg?style=flat-square)](https://coveralls.io/github/gpbl/denormalizr)```
npm install denormalizr --save
``````js
import { denormalize } from "denormalizr";
const denormalized = denormalize(entity, entities, entitySchema);
```### Documentation
* [API](#api)
* [Examples](#examples)
* [Denormalize a single object](#denormalize-a-single-object)
* [Denormalize a list of objects](#denormalize-a-list-of-objects)
* [Denormalize by passing the id](#denormalize-by-passing-the-id)
* [Denormalize by passing a list of ids](#denormalize-by-passing-a-list-of-ids)
* [Recursive schemas](#recursive-schemas)
* [Usage with Immutable](#usage-with-immutable)
* [Changelog](CHANGELOG.md)## API
```
denormalize (entity, entities, schema) -> Object|Array|Immutable.Map|Immutable.List
```### Params
**entity** `{Object|Array|Number|String|Immutable.Map|Immutable.List}`
> The entity to denormalize, its id, or an array of entities or ids.
**entities** `{Object|Immutable.Map}`
> An object to entities used to denormalize entity and its referred entities.
**entitySchema** `{schema.Entity}`
> The normalizr schema used to define `entity`.
### Returns
The denormalized object (or Immutable.Map), or an array of denormalized objects (or an Immutable.List).
## Examples
For the following examples, consider to have a JSON response from a REST API consisting in a list of articles,
where each article has a `author` field.```json
{
"articles": [{
"id": 1,
"title": "10 mindblowing reasons to prefer composition over inheritance",
"author": {
"id": 1,
"name": "Dan"
},
}, {
"id": 2,
"title": "You won't believe what this high order component is doing",
"author": {
"id": 1,
"name": "Dan"
}
}]
}
```To normalize this response with normalizr, we can define two Schemas: `articleSchema` and `authorSchema`.
```js
import { normalize, schema } from 'normalizr';const articleSchema = new schema.Entity('articles');
const authorSchema = new schema.Entity('authors');
const articleList = new schema.Array(articleSchema);articleSchema.define({
author: authorSchema,
});const normalized = normalize(response, {
articles: articleList,
})
```This way we have the usual normalized object with entities:
```js
// content of normalized
{ entities:
{ articles:
{ '1':
{ id: 1,
title: '10 mindblowing reasons to prefer composition over inheritance',
author: 1 },
'2':
{ id: 2,
title: 'You won\'t believe what this high order component is doing',
author: 1 } },
authors:
{ '1':
{ id: 1,
name: 'Dan' } } },
result: { articles: [ 1, 2 ] } }
```Let say we want to display the articles with ids `1` and `2`, and for each article its author.
In order to get the whole author object for each article, we need to loop over the author entities:
```js
const articleIds = [1, 2];
const articles = articleIds.map(id => {
const article = normalized.entities.articles[id];
article.author = normalized.entities.authors[article.author];
})
```We are basically reverting to the original JSON response. We are, indeed, *denormalizing*.
Without the need to know the entity's shapes, we can use denormalizr to simplify this process. Thus:
```js
import { denormalize } from 'denormalizr';const articles = denormalize([1,2], normalized.entities, articleList);
````articles` contains now the selected articles with the authors in them:
```js
// console.log(articles)
[ { id: 1,
title: '10 mindblowing reasons to prefer composition over inheritance',
author: { id: 1, name: 'Dan' } },
{ id: 2,
title: 'You won\'t believe what this high order component is doing',
author: { id: 1, name: 'Dan' } } ]
````denormalize()` accepts as first parameter the **entity** we want to denormalize, which can be a
single object, an array of object, a single id or an array of ids.
The second parameter is the whole **entities** object, which is consumed when the **entity schema** (third
parameter) has references to one or more entities.### Denormalize a single object
```js
const article = normalized.entities.articles['1'];
const denormalized = denormalize(article, normalized.entities, articleSchema);
```
```js
// console.log(denormalized)
{
id: 1,
title: 'Some Article',
author: {
id: 1,
name: 'Dan'
},
}
```
### Denormalize a list of objects```js
const article1 = normalized.entities.articles['1'];
const article2 = normalized.entities.articles['2'];const denormalized = denormalize([article1, article2], normalized.entities, articleListSchema);
``````js
// console.log(denormalized)
[{
id: 1,
title: '10 mindblowing reasons to prefer composition over inheritance',
author: {
id: 1,
name: 'Dan'
},
},{
id: 2,
title: 'You won\'t believe what this high order component is doing',
author: {
id: 1,
name: 'Dan'
},
}]
```### Denormalize by passing the id
```js
const denormalized = denormalize(1, normalized.entities, articleSchema);
``````js
// console.log(denormalized);
{
id: 1,
title: '10 mindblowing reasons to prefer composition over inheritance',
author: {
id: 1,
name: 'Dan'
},
}
```### Denormalize by passing a list of ids
```js
const denormalized = denormalize([1, 2], normalized.entities, articleListSchema);
``````js
// console.log(denormalized)
[{
id: 1,
title: '10 mindblowing reasons to prefer composition over inheritance',
author: {
id: 1,
name: 'Dan'
},
},{
id: 2,
title: 'You won\'t believe what this high order component is doing',
author: {
id: 1,
name: 'Dan'
},
}]
```### Recursive schemas
Denormalizr can handle circular references caused by recursive schemas (see [#2](https://github.com/gpbl/denormalizr/pull/2)).
For example, take these schemas, where articles have an author property containing a list of articles:
```js
const articleSchema = new schema.Entity('articles');
const authorSchema = new schema.Entity('author');
const articleList = new schema.Array(articleSchema);articleSchema.define({
author: authorSchema,
});authorSchema.define({
articles: articleList,
});const JSONResponse = {
"articles": [{
"id": 2,
"title": "You won\'t believe what this high order component is doing",
"author": {
"id": 1,
"name": 'Dan',
"articles": [2],
},
}],
};const normalized = normalize(JSONResponse, {
articles: articleList,
});const article = data.entities.articles['2'];
const denormalized = denormalize(article, data.entities, articleSchema);console.log(denormalized.author.articles[0] === denormalized)); // true
```
## Usage with Immutable
Denormalizr works well with [immutable-js](https://facebook.github.io/immutable-js/), however recursive schemas are [not supported](https://github.com/facebook/immutable-js/issues/259):
```js
// This nested article contains only a reference to the author's id:
denormalized.author.articles[0].author === 1
```Related work:
* [denormalizr-immutable](https://github.com/dehbmarques/denormalizr-immutable).