hughsk / flat

:steam_locomotive: Flatten/unflatten nested Javascript objects

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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. */

image

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

  1. By not introducing a breaking change: add one more option like pureObjectsOnly. But this IMO is weird with the presence of the safe option.
flatten(cat, {
  pureObjectsOnly: true,
});
  1. 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.