user3913918
user3913918

Reputation: 29

post nested object as formdata using x-www-form-urlencoded content-type

I have to send the data of post method where headers content-type is set to "x-www-form-urlencoded".

Also this form-data is nested object. e.g.

const formData = { name: "hello", email:[email protected], education: { subject: "engilsh" ... } } }

Upvotes: 2

Views: 3384

Answers (3)

Macr1408
Macr1408

Reputation: 845

I know this post is really old, but since nobody truly answered the question I felt the urge to chime in. Basically a recursive function will do this, since I'm a bit lazy I asked AI to do it, here is the result

const transformObjectToQueryString = (obj, parentKey = null) => {
let queryString = '';

for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    const value = obj[key];

    // Construct the full key name
    const fullKey = parentKey ? `${parentKey}[${key}]` : key;

    if (typeof value === 'object' && value !== null) {
      // Recursively process nested objects
      queryString += transformObjectToQueryString(value, fullKey);
    } else {
      // Append key-value pair to the queryString
      if (queryString.length > 0) {
        queryString += '&';
      }
      queryString += `${encodeURIComponent(fullKey)}=${encodeURIComponent(value)}`;
    }
  }
}

return queryString;
};

I didn't fully test it with big objects, but it worked perfectly fine with a two levels deep object. At first glance I can see it has no "emergency stop" meaning that it won't stop until it finishes handling the object, be careful with your memory usage ;) Feel free to add a level variable and stop the function if the level is too deep like any other serializer does

Upvotes: 0

TimNode
TimNode

Reputation: 810

I assume that the problem you are experiencing is that the data received is shown as education: [object Object].

The easiest way to resolve this problem is to change the header from x-www-form-urlencoded to application/json. That way the object with the key education won't be serialised into [object Object]

Another way to resolve this (but hacky) is to serialise the data client side:

const formData = { name: "hello", email:[email protected], education: { subject: "engilsh" ... } } }
const formDataSerial = { raw: JSON.stringify(formData) }
// Send to server

And at the server, do another step of unpacking:

const dataSerial = formData.raw
const data = JSON.parse(dataSerial)
// Yay!

Upvotes: 1

mkkekkonen
mkkekkonen

Reputation: 1774

You can use the querystring module.

Post the data like this Express-like pseudocode:

const querystring = require('querystring');

// ...

router.post(
  'https://api/url',
  querystring.stringify(formData),
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
)

// EDIT: The querystring module does not work with nested objects. My bad. I'd perhaps suggest serializing the object into a JSON string.

Upvotes: 1

Related Questions