ljharb / qs

A querystring parser with nesting support
BSD 3-Clause "New" or "Revised" License
8.5k stars 729 forks source link

Stringify nested object so output only contains values #423

Closed Moucky closed 2 years ago

Moucky commented 2 years ago

I've been trying for a while to output a query string from a nested array. I'm using qs.stringify(data, { arrayFormat: 'brackets', indices: false, encode: false}) ) and the output I'm getting is 0[name]=first-name&0[value]=&1[name]=surname&1[value]=&2[name]=email&2[value]=&3[name]=contact-number&3[value]=&4[name]=.

I'd like the output to be first-name=&surname=&email=&contact-number= Is it possible or do I have to do something to the array before I use stringify?

ljharb commented 2 years ago

What is data?

Either way, if you're picking arrayFormat "brackets" and passing an array, you're going to get brackets.

The output you want is represented by this object (not an array):

{
  'first-name': '',
  surname: '',
  email: '',
  'contact-number': ''
}
Moucky commented 2 years ago

Thanks for the reply, sorry if I explained it incorrectly. Data is a serialized array of form data.

ljharb commented 2 years ago

Arrays are supposed to have brackets though. Form data is an object.

Moucky commented 2 years ago

My understanding is that a serialised array is an array containing objects, so I guess I am wondering if it is possible to stringify the array to only show the values of the objects within the array?

ljharb commented 2 years ago

I'm not familiar with any concept of a "serialized array" that works like that; a serialized array is just any array in a serialized format.

Can you provide an actual example of the exact data in the array? I can show you how to transform it.

Moucky commented 2 years ago

Thanks so much, I really appreciate the help. The serialised array is produced using a plain JS version of the jQuery function serializeArray().

The output is

[
    {
        "name": "first-name",
        "value": ""
    },
    {
        "name": "surname",
        "value": ""
    },
    {
        "name": "email",
        "value": ""
    },
    {
        "name": "contact-number",
        "value": ""
    }
]

I am trying to use stringify to replace the $.param() function so I do not have to use jQuery.

ljharb commented 2 years ago

In that case, try qs.stringify(Object.fromEntries(data), options).

However, if you're already using serializeArray, i'm not sure why you wouldn't use $.param?

Moucky commented 2 years ago

The result is empty unfortunately, if I do console.log( Object.fromEntries(data) ) if get {}.

I'm not using serializeArray() I'm trying to replace jQuery so I have an equivalent function that produces the same result. $.param is the last bit of jQuery to remove

ljharb commented 2 years ago

ohh right, because data is an array of objects. In that case, Object.fromEntries(data.flatMap(x => Object.entries(x))) should do it.

Moucky commented 2 years ago

That seems to be better but only giving the last object and includes "name" and "value", output is name=contact-number&value= instead of first-name=&surname=&email=&contact-number=. Any ideas? Sorry to be such a pain, I can't think of anything else to try.

ljharb commented 2 years ago

ha, sorry, i'm just winging this :-)

Try Object.fromEntries(data.map(x => [x.name, x.value]))

Moucky commented 2 years ago

That looks like it's done it! Thank you so much.