2017-04-17 30 views
7

我想使用Fable-Elmish和React Helpers上傳文件。但是,我無法解決如何在選擇文件時將表單事件轉換爲可以使用Fetch發送到服務器的內容。這是視圖:使用Fable-Elmish將React.FormEvent轉換爲BodyInit

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

我更新功能的相應部分:

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

和函數調用與API獲取:

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 
    } 

我如何可以轉換React.FormEvent進入需要獲取的BodyInit?

回答

1

原來我沒有正確使用FileList API。以下是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

您將需要創建一個新的FormData對象並將該文件追加到它。

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

然後更改您要postRecord電話傳遞,而不是文件FORMDATA。你需要獲取編碼它,但你只是傳遞原始數組文件。

至少這是我從fetch example上傳文件的理解。另外,帖子記錄對我來說看起來不太合適,是否只有一種可以使用的「發佈」方法? postRecord意味着它期待一種記錄類型。

+0

我已更新問題以包含我的最新代碼,並考慮到您的建議。這實際上使發佈請求,但文件不包括在內。請求有效載荷如下所示:------ WebKitFormBoundaryAkHYH5XIH8vT8kea Content-Disposition:form-data; name =「file.csv」 [object FileList] ------ WebKitFormBoundaryAkHYH5XIH8vT8kea-- –

+0

請在公用文件夾中搜索您的包併發布正在生成的代碼。另外如果你可以請發佈一個小型的repro項目,包括服務器;我們可以使用它來解決或修補Powerpack中的讀取聲明。 –

+0

repro在這裏:https://github.com/danoleary/FableFileUploadRepro –

1

我覺得Fetch.postRecord是你的問題,它設置Content-Typeapplication/json,當it should bemultipart/form-data

您需要使用原始提取API而不是powerpack包裝器,其內容爲like this