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

Possible to allow key's with '.'s in them? #96

Open
sorahn opened this issue Mar 7, 2020 · 4 comments
Open

Possible to allow key's with '.'s in them? #96

sorahn opened this issue Mar 7, 2020 · 4 comments

Comments

@sorahn
Copy link

sorahn commented Mar 7, 2020

I'm looking for a way to preserve keys that have .s in to use the same syntax as lodash's set/get.

Ideally something like this:

// Input
{
  some: {
    'key.with.dots': value
  }
}

// Output
{
  some['key.with.dots']: value
}

The problem I've found with using the transformKey option is they still get the . joining them.

I have this:

const flatData = flatten(data, {
  transformKey: key => (key.includes('.') ? `['${key}']` : key),
});

But the output looks like this. (extra . after some)

{
  some.['key.with.dots']: value
}

I've worked around the issue for now by looping through the flattend data and doing a string replace on .[ with [.

const fixedData = Object.entries(flatData).reduce((acc, [key, value]) => {
  const newKey = key.includes('.[') ? key.replace('.[', '[') : key;
  acc[newKey] = value;
  return acc;
}, {});
@rgraffbrd
Copy link

rgraffbrd commented Mar 12, 2020

@sorahn I think a feature would need to be added. But if you can use this package to unflatten as well, then you could just use a different delimiter like /. In which case, without transformKey, you would get:

{
  "some/key.with.dots": value
}

Using the same delimiter when unflattening you would get your original structure.

If you have / in your keys, try using transformKey with something like encodeURIComponent. (decodeURIComponent when unflattening)

@sorahn
Copy link
Author

sorahn commented Mar 13, 2020

@rgraffbrd Hmm, that might work. I'd have to think through it. We feed the flattened data into formControlNames (angular), then use lodash for updates (set/omit fields) and comparisons to the original data (get).

@rgraffbrd
Copy link

@sorahn Not up on my Angular, but are you essentially saying that you set a form control's name to the full path and then, using lodash, you patch the original data/object structure from a flattened object with the changes?

@sorahn
Copy link
Author

sorahn commented Mar 17, 2020

Yes that's pretty close. We flatten the object. and use the path as the form name for angular to manage. so roughly <input name="foo['bar.baz']">, Then we listen to all the form value changes where you get a callback that looks something like this.

(path, value) => {
  if (value === null) {
    return omit(path, value, data)
  }

  return set(path, value, data)
}

elsewhere, we are also using get to compare to the original value to mark a field as edited. So when you pass the path into our component it both sets it on the <input> and uses it to check to see if the field was edited.

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