Reputation: 355
This is probably much clearer with code. If I have a response like this.
{
id: "1",
container: {
sections: [
{
id: "a",
pages: [
{
id: "z"
}
]
}
]
}
}
I am really wanting to normalize the sections collection and the pages collection inside of them. I also need to get it back into this exact shape. The problem that is that container
does not have an id. Everything I try can't seem to get it back to this. I would imagine the normalized version of what I am going for would be something like.
{
// the thing that container is in
project: {
id: "1",
// maybe remove container key, and know I have to normalize
// and add the key again?
container: "?"
},
sections: {
id: "a": {
pages: ["z"]
},
pages: {
id: "z"
}
}
Any help would be appreciated. Again the sections and pages are really what I am trying to normalize and de-normalize without loosing data from the top level key
EDIT
To slightly rephrase the question I have found posts like this one Normalizr - is it a way to generate IDs for non-ids entity model?. That are trying to add ids to things that don't have them. I am not really wanting that because I do not want to normalize anything at the same level or above container
only below.
Upvotes: 0
Views: 2000
Reputation: 2203
You may include container as part of your project schema definition.
const { schema } = require('normalizr');
const pageSchema = new schema.Entity('pages');
const sectionSchema = new schema.Entity('sections', {
pages: [pageSchema],
});
const projectSchema = new schema.Entity('projects', {
container: {
sections: [sectionSchema],
},
});
In this case, container will not be normalized. It's difficult to treat them as entities as long as they don't posess any identifying properties. If they did, you could specify that property as idAttribute
.
Your best option is to transform API response an generate unique ids at some level between API and normalizr, but it won't give you any of the normal benefits you get with normalization as pointed out in the question you linked.
Here's how you denormalize an entity from normalized state using the above schema:
const { normalize, denormalize } = require('normalizr');
const data = {
id: "1",
container: {
sections: [
{
id: "a",
pages: [
{
id: "z"
}
]
}
]
}
};
const state = normalize(data, projectSchema);
// -> {"entities":{"pages":{"z":{"id":"z"}},"sections":{"a":{"id":"a","pages":["z"]}},"projects":{"1":{"id":"1","container":{"sections":["a"]}}}},"result":"1"}
denormalize(1, projectSchema, state.entities);
// -> {"id":"1","container":{"sections":[{"id":"a","pages":[{"id":"z"}]}]}}
Upvotes: 1