0

For an Angular(v14) application, I have a requirement to "POST the following form-encoded parameters to a given URL for a list of items where n is the zero based index of the lines"

Format:

 ItemNo[n]=<Item Identifier>
 Description[n]=<Item Identifier>

So, for example, 3 items would be like so:

 ItemNo[0]=1001
 Description[0]=a wonderful item
 ItemNo[1]=1002a
 Description[1]=something
 ItemNo[2]=1002c
 Description[2]=another thing

On my end, the items I need to POST in the form-encoded format are in an array like so:

 [
     { ItemNo: '1001', Description: 'a wonderful item' },
     { ItemNo: '1002a', Description: 'something' },
     { ItemNo: '1002c', Description: 'another thing' },
 ]

So I've been trying to figure out how to get the array of items into the correct format: Form-encoded, without much luck. Hoping someone can help!

I've found quite a few similar questions, (though I'm unsure if I am using the most appropriate search terms) but Angular evolves so quickly that each time I try to implement a suggestion, I find the suggested solution uses one or more depreciated methods, so I've ended up with quite a mess of failed attempts!

I've written a function which will rewrite my array to add the indexing to the keys, so now I've got:

 [
    { ItemNo[0]: '1001', Description[0]: 'a wonderful item' }
    { ItemNo[1]: '1002a', Description[1]: 'something' }
    { ItemNo[2]: '1002c', Description[2]: 'another thing' }
 ]

But how can I get this into a form-encoded type? Everything I have tried that seemed promising (most recently DefaultUrlSerializer()) seems to give me results like

 "/?0=%5Bobject%20Object%5D&1=%5Bobject%20Object%5D"

(not keyname=value)

Also, on my http.post() method, what should the incoming type be, to be posting "form-encoded"? I'm guessing string?

Solution Discarding my extra function to add the indexes to the keys, the final solution is:

 doFormParams(items: any[]): HttpParams {
  let params = new HttpParams();
  items.forEach((item, index) => {
    for(const key in item){
    params = params.append(`${key}[${index}]`,`${item[key]}`);
    }
  });
  return params;
}

Some users have pointed out that this would be easier to send as a JSON object. I agree, this would be my default. However the third party who has given me this requirement is well established and uses this same method to receive data from many sources, so I don't really expect them to modify their ways just to suit my preference! Once I knew the method I needed, the solution was simple enough.

Ego Placebo
  • 157
  • 2
  • 14
  • Seems like a better way to handle such data would be to send it as a JSON object instead of converting it to url encoded. – svarlitskiy Jul 19 '23 at 06:54
  • That is not my choice, hence my very first statement that "I *have a requirement* to..." If it was up to me, of course I'd send a JSON object! – Ego Placebo Jul 19 '23 at 07:05
  • Well you should let those that set the requirement that there is a limit to how long a url can be. After 2000 characters some servers will start rejecting the posts. See [What is the maximum length of a URL](https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers) for some more in depth info. – svarlitskiy Jul 19 '23 at 07:16

1 Answers1

0

Use HttpParams class https://angular.io/api/common/http/HttpParams:

doFormParams(items: any[]): HttpParams {
  let params = new HttpParams();
  items.forEach((item, index) => {
    // do something
  });
  return params;
}

const headers = {
  'Content-Type': 'application/x-www-form-urlencoded'
};

this.http.post(url, params.toString(), { headers });
Evgeny Gurevich
  • 475
  • 3
  • 5
  • it's **not** neccesary use a HttpPatams. You pass any object to post. Usually you pass a JSON object, not a string. It's strange in a post you need pass a string to the server. So, the problem Ego have is in the server side. e.g. In .NET generally you get the answer from a post using `[fromBody]`. – Eliseo Jul 19 '23 at 07:08
  • Perfect, thankyou :) – Ego Placebo Jul 19 '23 at 07:10
  • @Eliseo - this is facilitating a third party, where they require this data to be sent to them as form-encoded in the format specified. I assume they have others send to the same, from multiple different frameworks. If there is some other way to send form-encoded data to an url from Angular, feel free to let me know, rather than just saying what should not be required :) – Ego Placebo Jul 19 '23 at 07:15
  • `JSON.stringify(myObject)` – Eliseo Jul 19 '23 at 07:38
  • Thanks for the input, however JSON.stringify does not form-encode the data, which is specified in the requirement. (I have verified with the third party that they in fact mean 'application/x-www-form-urlencoded'. The third party receives data via the same method from others, which is already established. I do not expect them to change their ways just for me, lol! – Ego Placebo Jul 20 '23 at 06:18