Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert React.FormEvent to BodyInit using Fable-Elmish

I am trying to upload a file using Fable-Elmish and the React Helpers. However, I can't work out how to convert the form event when a file is selected into something that I can send off to the server using Fetch. This is the view:

R.input [
        ClassName "input-control" 
        Type "file"
        OnChange (fun x -> FileUploaded x.target |> dispatch )
    ] []

The corresponding part of my update function:

 | FileUploaded file ->
    model, Cmd.ofPromise postCsv file FetchSuccess FetchFailure

And the function to call the api with fetch:

let postData input =
    let formData = FormData.Create()
    formData.append("file.csv", input?files)
    let defaultProps =
        [ RequestProperties.Method HttpMethod.POST
        ; RequestProperties.Body (formData |> unbox)]
    promise {
        return! Fable.PowerPack.Fetch.fetch ("/api/data") defaultProps
    }

How can I can convert the React.FormEvent into the BodyInit that fetch needs?

like image 417
Dan O'Leary Avatar asked Apr 17 '17 18:04

Dan O'Leary


2 Answers

Your going to need to create a new FormData object and append the file to it.

let formData = FormData.createNew formData.append("file", file.[0])

Then change your call to postRecord to pass formData instead of file. You need fetch to encode it, but you are just passing the raw array of files.

At least that is my understanding from the fetch example on uploading a file. Also, post record looks wrong to me, is there just a "post" method you could use? postRecord implies it is expecting a record type.

like image 135
Mizzle-Mo Avatar answered Nov 16 '22 02:11

Mizzle-Mo


I think Fetch.postRecord is your problem, it sets Content-Type header to application/json, when it should be multipart/form-data.

You need to use raw fetch API, instead of powerpack wrapper, something like this.

like image 43
Eugene Tolmachev Avatar answered Nov 16 '22 01:11

Eugene Tolmachev