I'm a off-grid developer from the Amazon forest ๐ด.
gpbl / denormalizr Goto Github PK
View Code? Open in Web Editor NEWDenormalize data normalized with normalizr
Home Page: https://www.npmjs.com/package/denormalizr
License: MIT License
Denormalize data normalized with normalizr
Home Page: https://www.npmjs.com/package/denormalizr
License: MIT License
I'm a off-grid developer from the Amazon forest ๐ด.
I'm trying to go through tutorial, but i'm stuck since denormalize simply isn't working and, instead of array of denormalized articles gives me this { '0': 1, '1': 2 }
Normalizr can normalize recursive models, but can't denormalize them -- there was a commit to allow it, but it caused a regression and was reverted several months ago. If nothing else it might be worthwhile to mention this as a valid use case even though it is otherwise deprecated. Just a thought, totally understand if it's not worth reviving/maintaining the project.
First, thanks for the library. I was getting pretty tired of denormalising!
I found that when denormalising attributes that are null
they are returned as empty objects, {}
, instead of null
.
I can get around this, I just thought I would see if it is deliberate or accidental.
I'm trying to test this, but I still can't figure out. Nor I know if it has performance issues. Can someone explain it?
Hello and thank you for your awesome contribution!
Quick comment: I would like to denormalize array of entities like this:
denormalize(arrayOfNormalizedEntities, entities, arrayOf(entitySchema))
It was my first try as it is analogical to
normalize(arrayOfRawEntities, arrayOf(entitySchema))
What do you think?
My API gives me one level of nested associations in general though I have complete structure of normalizr
schemas assembled so denormalization often fails with Cannot read property 'x' of undefined
.
Options discussed elsewhere (if i recall correctly):
limit
param of denormalize
to restrict nestingFor now I will try second approach and see how it works out.
Any advices much appreciated!
I copied the code from the example:
const { normalize, Schema, arrayOf } = require("normalizr/dist/normalizr.min.js");
const { denormalize } = require("denormalizr");
const articleSchema = new Schema('articles');
const authorSchema = new Schema('author');
const articleList = arrayOf(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 = normalized.entities.articles['2'];
const denormalized = denormalize(article, normalized.entities, articleSchema);
console.log(denormalized.author.articles[0] === denormalized); // true
The denormalized variable returns:
author: Object
id: 2
title: "You won't believe what this high order component is doing"
Which is great... but author is an empty object.
I have also had this problem when trying to implement this code with other normalised objects, I have tried using previous versions of the denormalizr too, but that too doesnt work. I am using normalizr version 2.2.1 on Chromium web browser.
Just wondering what is the need for the second argument that is supplied with list of all entities. Isnt it possible to denormalize a single entity given a schema?
I have the need to call a function objects, including nested objects, after they've been denormalized. Since it includes nested entities, if I waited until the entire object was denormalized I'd have to re-traverse all of the nested schemas manually, which I'd like to avoid.
To give more context of my specific use-case, I'm storing raw data in a normalized store and I need to instantiate classes from these object on the way out.
I think it would be a fairly simple/straightforward change to the denormalizeObject
function:
function denormalizeObject(obj, entities, schema, bag) {
let denormalized = obj
Object.keys(schema)
.filter(attribute => attribute.substring(0, 1) !== '_')
.filter(attribute => typeof getIn(obj, [attribute]) !== 'undefined')
.forEach(attribute => {
const item = getIn(obj, [attribute]);
const itemSchema = getIn(schema, [attribute]);
denormalized = setIn(denormalized, [attribute], denormalize(item, entities, itemSchema, bag));
});
// New line
const { transform = _.identity } = bag
return transform(denormalized);
}
The one issue that I see is that the bag
field is the last argument to denormalize. I think just passing the transform
key directly there should be fine but there's a non-zero chance it would collide with a key during denormalization if that happened to be a string key. Super edge-case IMHO, but we could either make that key more specific (e.g. transformObject
) or prefix it with a _
(e.g. _transform
or _transformObject
) if you think that's an issue.
Let me know if this makes sense and I can put together a PR with specs.
I have lodash
declared as a dependency in my app. The declaration is the following:
"lodash": "^4.15.0",
Also, I have found out that you are also depending on lodash, but with fixed version 4.16.3
. It causes that I have two lodash
instances included into my webapp bundle 4.16.4
and 4.16.3
.
Do you mind to make lodash version more flexible? It follows semver rules, so I'd trust @jdalton, that here will be no breaking changes during minor releases.
I'm trying to normalize
and denormalize
a simple object structure, but I'm really stuck. I think that I do everything according documentation, but without any luck.
You can try my example here: https://jsbin.com/heyayodagi/5/edit?js,console
Code:
const original = {
id: 'chart-1',
chart_title: 'Back to the future',
series: [{
id: '11',
label: 'Visitors',
color: '#ff0000',
dashed: false,
yaxis: '133'
},
{
id: '22',
label: 'Visitors prediction',
color: '#ff5500',
dashed: true,
yaxis: '133'
}],
y_axes: [{
id: '133',
title: 'Total revenue'
}],
x_axis: {
title: 'Days'
}
};
// SCHEMA
const lineChartSchema = new Schema('line_charts', { idAttribute: 'id' });
const seriesSchema = new Schema('series_out', { idAttribute: 'id' });
const yAxeSchema = new Schema('y_axes_out', { idAttribute: 'id' });
lineChartSchema.define({
series: arrayOf(seriesSchema),
y_axes: arrayOf(yAxeSchema)
});
// NOW WE WILL NORMALIZE IT
const norm = normalize(original, lineChartSchema);
console.log('Normalized version:');
console.log(norm);
// NOW WE WILL TRY TO GO BACK AND DENORMALIZE
// try 1
const denorm = denormalize(norm.entities.line_charts['chart-1'], norm.entities, lineChartSchema);
// try 2 - docs say first parameter can be "a single id"
// const denorm = denormalize('chart-1', norm.entities, lineChartSchema);
console.log('Trying to de-normalize it back:');
console.log(denorm);
But denormalized output looks like this:
{
'id': 'chart-1',
'chart_title': 'Back to the future',
'series': {
'0': '11',
'1': '22'
},
'y_axes': {
'0': '133'
},
'x_axis': {
'title': 'Days'
}
}
Am I doing something wrong, or there is an issue in this library?
Supporting unpkg.com is really useful when testing denormalizr
in a JavaScript playgrounds like JSBin or CodePen.
I found this https://unpkg.com/[email protected]/ , but there is no UMD version of a library.
As an example, normalizr
can be found on https://unpkg.com/[email protected]/dist/normalizr.min.js
Normalizr allows you to pass a function to idAttribute
instead of a string but as denormalizr seems to assume that the returned value from schema.getIdAttribute
is a string it won't work.
Line 23 in 3213960
I guess I could work around this issue by plucking the id attributes from my objects before denormalizing but that doesn't feel optimal...
The README has:
// Denormalize a list
const denormalized = denormalize([article], normalized.entities, articleListSchema);
console.log(denormalized);
// [{
// id: 1,
// title: 'Some Article',
// author: {
// id: 1,
// name: 'Dan'
// },
// }]
But it doesn't actually return an array, and the information isn't nested. Instead it simply gives a key to the author. This is what I get using the code as given in the example in the README:
const denormalized = denormalize([article], normalized.entities, articleListSchema);
console.log(denormalized);
{0: {
author: 1,
id: 1,
title: "Some Article"
}}
I'm not sure how to actually get an array back with the author nested. Any help would be greatly appreciated. Thanks!
Now that Typescript became popular, would you mind also provide typescript definitions?
Normalizr 3.2+ has built-in denormalization support, so this package will be deprecated as soon as paularmstrong/normalizr#238 is closed and released.
A big thanks to the contributors which helped to improve this library and to @paularmstrong for adding this feature to normalizr! โค๏ธ
First off, thanks for starting this project-- having a natural way to denormalize nested entities is definitely a helpful convenience.
I notice the README documentation needs some minor updating, as what is currently there doesn't perform as expected.
const article = normalized.entities.articles[0];
articles
is an object indexed from 1, so ...articles['1']
to access the first article.
Second, the last example doesn't return what it should.
const denormalized = denormalize([1], normalized.entities, articleSchema);
denormalized === { '0': 1 } // instead of [{id:1,title:'Some Article'...}]
In my mind, denormalizr is most useful when passing large nested objects to a component using connect
. But currently it always returns a new object, so the component re-renders on every action.
denormalize
should always return the same (strictly equal) result unless:
I believe this could be accomplished fairly simply using a cache of denormalized resources.
So in the examples you mentioned that we can denormalize using 4 different overloads/types for the input parameters as follow:
Well. Actually when I try normalizing by passing the id, it works like this:
Case A:
const denormalized = denormalize(1, normalized.entities, articleSchema);
Case B:
But when I pass a list of the same id, it don't, like this:
const denormalized = denormalize([1], normalized.entities, articleListSchema);
I checked the test files and I noticed you use to loop on it manually like this:
Case C:
const denormalized = [1].map(id => denormalize(id, normalized.entities, articleListSchema));
So am I missing to have Case B working without using loop like in Case C. Thanks in advance!
The newest update (v0.5.1) has introduced a bug which causes related entities not being populated at all. For instance, if we have [Group] 1 --> * [User], the users
property is not populated in the final group
object.
Seems to be related to the new browsers
property added to package.json
since removing this line restores the correct behaviour.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.