sveltejs / kit

web development, streamlined
https://svelte.dev/docs/kit
MIT License
18.73k stars 1.95k forks source link

Improve FormData logging (or documentation) #4198

Closed bluepuma77 closed 2 years ago

bluepuma77 commented 2 years ago

Describe the problem

I'm always frustrated when working with await event.request.formData() because it is not easily log-able.

export async function post(event) {
    const body = await event.request.formData()
    console.log('body', body)
    console.log('body', body.entries())
    console.log('body', body.keys())
    console.log('body', body.values())
    ...

All those simple measures during development to see if form data arrives and what values are contained do not work with current SvelteKit:

body FormData {}
body Object [Generator] {}
body Object [Generator] {}
body Object [Generator] {}

Especially the fact that a simple console.log(body) yields no sense-making output is very irritating to me. As a SvelteKit newbie it took me an hour to understand that it's not a problem with the data transfer but only with the way I want to display the data.

Describe the proposed solution

const body = await event.request.formData();
console.log(body);

should show body content, formatting doesn't really matter.

[ [ "name": "Rich Harris" ], [ "hobbies", "svelte" ], [ "hobbies": "journalism" ] ]

Alternatives considered

Add an example to the endpoint body parsing documentation.

const body = await event.request.formData();
const entries = [...body.entries()];
// [ [ "name": "Rich Harris" ], [ "hobbies", "svelte" ], [ "hobbies": "journalism" ] ]

Importance

would make my life easier

Additional Information

No response

Conduitry commented 2 years ago

I don't think we want to mess with the toString on this polyfill (nor on the native FormData in environments where we can use that). I have mixed feelings about whether we should include an example of this, rather than just linking to MDN.

Rich-Harris commented 2 years ago

Yeah, we definitely don't want to be monkey-patching or mucking about with prototypes. The MDN FormData documentation also isn't much help in this regard though.

Logging is pretty straightforward once you know how...

const body = await event.request.formData();

// to get everything
console.log(...body); // ["name", "Rich Harris"] ["hobbies", "svelte"], ["hobbies", "journalism"]

// if you know you don't have duplicates
console.log(Object.fromEntries(body)); // { name: "Rich Harris", hobbies: "journalism" }

...and the same thing applies to lots of similarly-shaped objects (Map, URLSearchParams, etc).

I'm always a little torn in situations like this. If Svelte/SvelteKit docs need to show how to use various web APIs (including things like Request and Response) then they'll quickly get bloated. At the same time, many developers will encounter those APIs for the first time while using Svelte, and it can be hard to find relevant/high quality documentation elsewhere. There's no right answer.

newlegendmedia commented 2 years ago

I just learned something from that solution but I am not in favor of putting general javascript recipes into the Svelte (Kit) docs. imho.

bluepuma77 commented 2 years ago

Just had a similar experience with request.headers. This time I could log it, but not pass it around.

console.log(request.headers) works, JSON.stringify(request.headers) returns {}. console.log(...request.headers) works, JSON.stringify(...request.headers) returns only parts, JSON.stringify([...request.headers]) works again.

Object.fromEntries(request.headers) works perfectly, you just need to know about it.

Next: how to get the cookie?

console.log(request.headers.cookie)
console.log(request.headers['cookie'])
console.log(request.headers.get('cookie'))

The SvelteKit docs shows how to set cookies, but not how to get cookies.

Rich-Harris commented 2 years ago

Again though, Request and Headers are web APIs, not SvelteKit APIs. We can't realistically make it our responsibility to show developers how to use the web platform itself.

Calling a function with spread syntax (JSON.stringify(...foo)) is roughly equivalent to this...

JSON.stringify(foo[0], foo[1], foo[2], ...)

...which won't work, because JSON.stringify takes a single value argument followed by options.

bluepuma77 commented 2 years ago

Thanks for clarification, will close issue.