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

Add arrayBrackets option #112

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

MitchLillie
Copy link

Hi all!

So, not sure if this is welcome or not, but I thought I'd give it a shot. I noticed a lot of issues where people were wanting some way to support the syntax of lodash's set/get, among other tools. I created an option, arrayBrackets, that wraps array indexes in brackets and omits the delimiter. I'm happy to make any changes, please let me know.

@MitchLillie
Copy link
Author

@timoxley Is there any interest in this? Happy to adjust, or just close if this is too beyond the pale

@marceloloureiro
Copy link

Yes, that functionality would be great.

I know your target is not java, but I'll give this example as a usage scenario.

One use case would be turning an array of complex objects into a url query string.

The syntax without the square brackets doesn't work for this if you're using a api written in java spring boot, for example.

For example:

const data = {
 arr: [{id: 1}, {id:2}]
};

I would like to translate this array of complex objects into a query string by using

const queryString = new URLSearchParams(flatten(data, {arrayBrackets: true})).toString();

that would produce arr[0].id=1&obj[1].id=2 instead of arr.0.id=1&obj.1.id=2

In this scenario springboot automatically converts the data into an object of the class below

public class Data {
  @Getter @Setter
  private List<MyBean> arr = new ArrayList<>();
}

I don't know the formal specification of a url and it's search params, but I suspect that the way spring boot works must implement some specification, so it wouldn't be a scenario just for java, but for queries via url search params.

@marceloloureiro
Copy link

For the record, the proposed code in this PR breaks the unflatten method.

You need to refactor the code into the unflatten function for the reverse conversion to work.

The idea is to look for array keys, of type [key] and replace them with key.

There is no need to pass the arrayBrackets property, the code works both for the old notation, in the form item.index and for the form item[index]

//... unflatten function code

// Add this function to convert the array keys.
  function handleArrayBrackets(input) {
    const arrayItemsRegex = /\[(.*?)\]/g;
    const output = input.replace(arrayItemsRegex, ".$1");
    return output;
  }

 // The function above must be used on the code bellow
  target = Object.keys(target).reduce(function (result, key) {
    const type = Object.prototype.toString.call(target[key])
    const isObject = (type === '[object Object]' || type === '[object Array]')
    if (!isObject || isEmpty(target[key])) {
-      result[handleArrayBrackets(key)] = target[key] // <== HERE: handleArrayBrackets(key) instead of key
      return result
    } else {
      return addKeys(
        handleArrayBrackets(key), // <== HERE: handleArrayBrackets(key) instead of key
        result,
        flatten(target[key], opts)
      )
    }
  }, {})

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

Successfully merging this pull request may close these issues.

2 participants