15

After initiating a skeleton project from sveltekit app. my index has a form :

<script>
    let name
    let password

    async function submitit(){
       // console.log("name is :", name)
       // console.log("password is :", password)
       
     const doit = async () =>{
        let res = await fetch( 'formdata' ,{
        method : "post",
        headers: {        
        'Accept': 'application/json',
        'content-type' : 'text/html; charset=UTF-8',
        //'Content-Type': 'multipart/form-data'
        },
        body : JSON.stringify({
            name : "name",
            password : "password"
        })        
    })// fetch
    let results =await res.json()
    console.log( "xxxxxxxxxxxxxxxxxxxxx"    , results )
    return results
    }       

     doit().then(data =>{
         console.log("data log : " , data)
     })


    } //submitit


</script>









<form on:submit|preventDefault={submitit}>
    <p>
    <label>Name :
        <input type="text"  placeholder="name"   aria-label="name" required bind:value={name}>
    </label>
</p>
<p>
    <label>Password :
        <input type="password" placeholder="password"   aria-label="password" required  bind:value={password}>
    </label>
</p>
    <button type="submit">Submit</button>
</form>

my endpoint formdata.js

export async function post(request) {    

    console.log("formdata js log of request : ", request)
    
    return {
        
        status : 200,
        headers: {        
            'content-type': 'application/json'
        },
        body : {            
            message : "login form submitted the login credentials",
        }
    }

} 

When I click submit, the index.svelte returns the message "login form submitted the login credentials" and it is in the console.log of the browser. The cmd which is used to run the application using npm run dev, logs the dataform.js request and prints the following :

formdata js log of request :  {
  request: Request {
    size: 0,
    follow: 20,
    compress: true,
    counter: 0,
    agent: undefined,
    highWaterMark: 16384,
    insecureHTTPParser: false,
    [Symbol(Body internals)]: {
      body: <Buffer 7b 22 6e 61 6d 65 22 3a 22 6e 61 6d 65 22 2c 22 70 61 73 73 77 6f 72 64 22 3a 22 70 61 73 73 77 6f 72 64 22 7d>,
      stream: [Readable],
      boundary: null,
      disturbed: false,
      error: null
    },
    [Symbol(Request internals)]: {
      method: 'POST',
      redirect: 'follow',
      headers: [Object],
      parsedURL: [URL],
      signal: null,
      referrer: undefined,
      referrerPolicy: ''
    }
  },
  url: URL {
    href: 'http://127.0.0.1:3000/formdata',
    origin: 'http://127.0.0.1:3000',
    protocol: 'http:',
    username: '',
    password: '',
    host: '127.0.0.1:3000',
    hostname: '127.0.0.1',
    port: '3000',
    pathname: '/formdata',
    search: '',
    searchParams: URLSearchParams {},
    hash: ''
  },
  params: {},
  locals: {},
  platform: undefined
}

Notice the following: 1- there is no username or password fields in my form or the body json.stringify in the index.svelte but it is in the request log under the url section (both are empty despite the dummy text I entered in index.svelte)

2- body stream is readable. I indicated the application to accept/send json.

I also find this pr from Rich and have no idea if what I'm facing is because of this change. Here is the PR

I'm lost with this sveltekit. I had great experience with Sapper and I hope I could figure out sveltekit so I can go on and start developing my application but this is the first step in any application, process form data.

=================================================================

****************** update : Explain needed if possible ***************************** I still would like to understand how you got the event argument from this pr because in Rich's post, the code with + is the updated one. It doesn't mention event:

Updating endpoints Similarly, handlers receive a RequestEvent. Most GET handlers will be unchanged, but any handler that needs to read the request body will need to update:

-export async function post({ params, body }) {
+export async function post({ params, request }) {
+ const body = await request.formData(); // or request.json(), etc
  await do_something_with(params, body);
  return { status: 201 };
}

there is no mention in event anywhere. How did you get the keyword "event" as an argument for the function?

Marco
  • 1,051
  • 19
  • 41

2 Answers2

18

Your endpoint should now look like this:

export async function post(event) {
  const body = await event.request.json();
  console.log('request body: ', body );
  // ... the rest is the same as before
}

Before the change linked in the PR you referenced, the argument to post was called request and you could access request.body. Now, the argument is called event and you can access event.request, which is a standard web request object. See the SvelteKit docs.

Your endpoint could also be written like this to automatically destructure the request property (note the additional curly brackets around request):

export async function post({ request }) {
  const body = await request.json();
  console.log('request body: ', body );
  // ... the rest is the same as before
}
mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Geoff Rich
  • 4,726
  • 9
  • 22
  • It works and thank you for your help. I updated my question with a little request to understand how did you get that the function argument needed the event keyword? There is nothing in Rich's text or code that mentioned "event" keyword argument? Do you mind if you explain it to me so in the future I would be able to read those pr and be able to help myself. Thank you for all your help. – Marco Feb 06 '22 at 02:44
  • @Marco request in handle has been replaced with event. See https://github.com/sveltejs/kit/pull/3384 for details. Update occured on 19 Jan 2022. Look closely at the hooks.js example. But you are right, the info on that github pull link is not very clear. And the worst, _To access the request body use the text/json/arrayBuffer/formData methods, e.g. `body = await request.json()`_ is a terrible error message – zipzit Feb 20 '22 at 16:30
  • ```request.json is not a function``` – Oliver Dixon Jul 02 '22 at 08:15
5

You're right that the PR changed how you access the body. Now to access the request body in your endpoint you have to use:

const body = await request.json()

If you directly used your form to send the data (with action="/path/to/endpoint") you would use:

const body = await request.formData()

Edit: Note that the Response interface (request in SvelteKit) is a standard part of the Fetch API.

Docs on the request object (all methods)

See SvelteKit docs for +server.ts

Caleb Irwin
  • 398
  • 2
  • 5
  • Thanks for taking the time to comment. This issue deserves more attention because the endpoints are broken. As you can see from my code, I'm not using the action property. When I add const data = await request.json(), when compile using npm run dev, I get an error that request.json() is not a function. I don't know how to reach any of the maintainers to let them know or what to do to fix it. – Marco Feb 05 '22 at 21:00
  • Sorry, I couldn't be more helpful. I completely missed that in the docs they used object destructing (`post{( request })`) and your code didn't (`post(request)`). – Caleb Irwin Feb 07 '22 at 04:41