2017-04-17 4 views
7

Próbuję przesłać plik przy użyciu Fable-Elmish i Helperów reagujących. Nie mogę jednak ustalić, jak przekonwertować zdarzenie formularza, gdy plik zostanie wybrany na coś, co można wysłać do serwera za pomocą narzędzia Pobierz. To jest widok:Konwertuj React.FormEvent na BodyInit za pomocą Fable-Elmish

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

Odpowiednia część mojego funkcji aktualizacji:

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

a funkcja do wywołania API z pobierania:

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 
    } 

jaki sposób mogę przekonwertować React.FormEvent do BodyInit, które pobierają potrzebne?

Odpowiedz

1

Okazuje się, że nie korzystałem poprawnie z API FileList. Oto rozwiązanie robocze dla metody post:

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

Konieczne będzie utworzenie nowego obiektu FormData i dołączenie do niego pliku.

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

Następnie zmień swoje wezwanie do postRecord przekazać formData zamiast pliku. Potrzebujesz go do zakodowania, ale przechodzisz przez surową tablicę plików.

Przynajmniej to jest moje zrozumienie z fetch example w sprawie przesyłania pliku. Poza tym post-rekord wygląda mi nie tak, czy można użyć tylko metody "postu"? postRecord sugeruje, że oczekuje typu rekordu.

+0

Zaktualizowałem pytanie, aby uwzględnić mój najnowszy kod, biorąc pod uwagę Twoje sugestie. To faktycznie sprawia, że ​​żądanie post, ale plik nie jest wliczony w cenę. Ładunek żądania wygląda następująco: ------ WebKitFormBoundaryAkHYH5XIH8vT8kea Content-Disposition: form-data; name = "file.csv" [obiekt FileList] ------ WebKitFormBoundaryAkHYH5XIH8vT8kea-- –

+0

Proszę przeszukać swój pakiet w folderze publicznym i opublikuj wygenerowany kod. Również jeśli możesz proszę opublikuj mały projekt repro zawierający serwer; możemy go użyć do rozwiązywania problemów lub łatania deklaracji pobierania w Powerpack. –

+0

repro jest tutaj: https://github.com/danoleary/FableFileUploadRepro –

1

myślę Fetch.postRecord jest Twój problem, ustawia Content-Type nagłówek application/json, gdy it should bemultipart/form-data.

Musisz użyć interfejsu API pobierania surowego, zamiast pakunku z pakietem Powerpack, coś w rodzaju like this.