Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why cats are also flattened? 🐈 #118

Open
nikitaeverywhere opened this issue Nov 12, 2020 · 1 comment
Open

Why cats are also flattened? 🐈 #118

nikitaeverywhere opened this issue Nov 12, 2020 · 1 comment

Comments

@nikitaeverywhere
Copy link

nikitaeverywhere commented Nov 12, 2020

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!

@dennisMeeQ
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants