Skip to content

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