hughsk / hughsk/flat

Why cats are also flattened? 🐈

Open
#118 1 comment 18 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
1.8k
Forks
197
PR merge metrics
No merged PRs in 30d

Description

Hello! Thanks for the great and popular library.

This is a kind of library design-level question.

## The code:

```javascript
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

```javascript
{
"cat.instance": Cat { name: 'Cosmonaut' }
}
Meow. /* Happy healthy cat. */
```

## Actual result

```javascript
{
"cat.instance.name": 'Cosmonaut'
}
undefined /* The cat can't talk anymore. */
```

![image](https://user-images.githubusercontent.com/4989256/98976140-a953fe00-251f-11eb-9a4e-01f122682214.png)

## 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):

```typescript
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:

```javascript
> flat({ id: new ObjectID('catcosmonaut') })
{
id: ObjectId {
[Symbol(id)]:
}
}
```

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.

```javascript
flatten(cat, {
pureObjectsOnly: true,
});
```

2. 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!

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reproducing the flatten() examples with the Cat instance and MongoDB ObjectID, then inspect how the existing safe option handles them. The issue needs a decision between a new pureObjectsOnly option and changing safe; done means an agreed behavior that preserves the MongoDB update use case.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, mongodb
Domain
backend, database
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.