Why cats are also flattened? π
nikitaeverywhere opened this issue Β· comments
Hello! Thanks for the great and popular library.
This is a kind of library design-level question.
The code:
import flatten from 'flat';
class Cat {
name = 'Cosmonaut';
meow() {
console.log('Meow.');
}
}
const result = flatten({
cat: {
instance: new Cat(),
},
});
console.log(result);
console.log(result['cat.instance']?.meow());
Expectation
{
"cat.instance": Cat { name: 'Cosmonaut' }
}
Meow. /* Happy healthy cat. */
Actual result
{
"cat.instance.name": 'Cosmonaut'
}
undefined /* The cat can't talk anymore. */
Question
Why flatten any non-Object-prototype objects? I.e. why not only objects that satisfy Object.getPrototypeOf(obj) === Object.prototype
? Is there a use-case for flattening custom (prototyped) objects?
My use case
I was happily using this convenient library with MongoDB queries, to flatten this for example (oversimplified):
function updateExistingObject({ $set }: { $set: DbObject }) {
collection.updateOne({ _id: ID }, { $set: flatten($set) });
}
updateExistingObject({
$set: {
name: 'Cosmonaut',
props: {
related: new ObjectID("catcosmonaut"), // the problem is this
canMeow: true,
// ...
}
}
});
However, soon I realized that Mongo's ObjectID
also gets flattened in a very weird way:
> flat({ id: new ObjectID('catcosmonaut') })
{
id: ObjectId {
[Symbol(id)]: <Buffer 63 61 74 63 6f 73 6d 6f 6e 61 75 74>
}
}
This breaks MongoDB's updateOne
.
Suggestions
- By not introducing a breaking change: add one more option like
pureObjectsOnly
. But this IMO is weird with the presence of thesafe
option.
flatten(cat, {
pureObjectsOnly: true,
});
- Breaking change: make
safe
also not transforming non-"pure" objects, as well as arrays (this is enough for my case, as I never update arrays like this in MongoDB).
Request for comments
I would be happy to know any opinions on this and contribute. Thanks!
First of all +1 for the cats π€£
But on a serious note: Came here to look for a solution for exactly @ZitRos 's problem. I was happily flattening objects before throwing them into mongo/mongoose updates until I stumbled upon this behaviour.