Hi,
I was wondering where in the documentation I can find the limitations of the layout we get for mongoose “embedded documents” with different structures.
An embedded doc with simple fields would be rendered as an “indented” UI part on the details page:
Is this by design? How do you suggest working around this? Working with flat documents is against mongodb design philosophy and we want to make use of complex structures in our data model when its the right solution.
Thanks!
Expected behavior
Allow at UI to render at least a single level of indentation even with array fields.
Actual behavior
Fallsback to JSON edit widget
Context
Please provide any relevant information about your setup.
Sadly this is the best I can propose so far, embedded document with only one level will support editing each field directly, but if you add another level (another deep object or an array) we fallback to the JSON editor.
However, I find your feedback really interesting and supporting nested / deep structure could be a nice feature.
I’m adding your feedback to our productboard.
Sorry for inconvenience, and thanks for your feedback
Thanks Steve,
I thought one way to workaround the problem is to treat those embedded docs as a “hasOne” relationship.
Such that they appear on the left side navigation and have their own edit screen.
Would that be possible? how would you go about doing this?
Yes indeed this is possible, but only for array of embedded. The array must no be deep in an embedded object, it must be at level one of the model, for instance:
Using this type of declaration, you will be able to see the products records as related data on the left panel you spoke about in your previous message.
Also, as @louis pointed out, retrieving deeper levels of data and relocating them at the top level of the record using a smart field might also fit your need
Hi Guys,
I believe when not too many fields are involved indeed a SmartField could be a reasonable workaround.
This helper function could be useful: (uses lodash)
Few points to note.
Field names are derived from the path here. Periods (".") are replaced with underscores ("_") which are transformed by Forest’s layouts to spaces. works great for us since we dont have underscores in field names anyway and lodash+mongodb use periods to denote hierarchy.
You might want some other field name / path logic.
We use here the full “path” on the output doc within the “set” handler since otherwise (if setting a nested object) the entire embedded doc is overridden due to how “$set” behaves when provided with a full object and not a path. @louis please note the example in the woodshop shows how to do it in a destructive way which may mislead developers.
One last comment, the woodshop example does not return the output doc form “set” handler and the docs say it’s required. Not sure what it affects (maybe other smart fields downstream) so I returned it to be on the safe side.
Quick update for anyone who is interested - this is the version we use today which allows specifying custom names and supports also embedded enum fields.
function extractEmbeddedFieldToRoot({ path, type, enums, name }) {
const fieldDefinition = {
field: name || path.replace('.', '_'),
type,
get: (doc) => {
return _.get(doc, path);
},
set: (doc, value) => {
doc[path] = value;
return doc;
},
};
if (type === 'Enum') {
if (enums && enums.length) {
fieldDefinition.enums = enums;
} else {
throw new Error('Enum typed fields must provide the enum values');
}
}
return fieldDefinition;
}