Skip to content

Instantly share code, notes, and snippets.

@octet-stream
Last active June 4, 2017 20:05
Show Gist options
  • Select an option

  • Save octet-stream/ea3638f13be6d427fede61a5c35bdbfb to your computer and use it in GitHub Desktop.

Select an option

Save octet-stream/ea3638f13be6d427fede61a5c35bdbfb to your computer and use it in GitHub Desktop.
File uploads in GraphQL + Apollo Client
import Client from "apollo-client"
import Transport from "./FormDataHTTPFetchNetworkInterface"
const connection = new Client({
networkInterface: new Transport("http://localhost:3310/graphql") // Your GraphQL endpoint
})
export default connection
// Remove this polyfill if you don't use SSR
import fetch from "isomorphic-fetch"
import {printAST, HTTPFetchNetworkInterface} from "apollo-client"
import toFormData from "./toFormData"
class FormDataHTTPFetchNetworkInterface extends HTTPFetchNetworkInterface {
fetchFromRemoteEndpoint({request, options}) {
// Transform variables obj to FormData
const body = toFormData(request.variables, "variables")
// Add specific GraphQL fields
body.append("operationName", request.operationName)
body.append("query", printAST(request.query))
return fetch(this._uri, {
...this._opts,
...options,
method: "POST",
headers: {
Accept: "*/*",
...options.headers,
},
body
})
}
}
export default FormDataHTTPFetchNetworkInterface
const connection from "./connection"
const mutation from "./mutation.graphql" // graphql-tag/loader required
const variables = {
file: "<your file can be right here>"
}
const onFulfilled = ({data}) => console.log(data)
const onRejected = err => console.error(err)
connection.mutate({mutation, variables}).then(onFulfilled, onRejected)
/**
* @author Nick K. https://github.com/octet-stream
* @license MIT
*/
// Remove this one if you are not using SSR
import FormData from "isomorphic-form-data"
// You can manually replace these helpers.
import isPlainObject from "lodash/isPlainObject"
import isEmpty from "lodash/isEmpty"
const isArray = Array.isArray
/**
* Transform given object to form-data
*
* @param object state
*
* @return FormData instance
*/
function toFormData(obj, rootKey) {
const fd = new FormData()
/**
* Append object fields to FormData instance
*
* @param null|string key – parent field key
* @param any value
*
* @api private
*/
function append(key, value) {
for (const [k, v] of Object.entries(value)) {
const name = key ? `${key}[${k}]` : key
if ((isArray(v) || isPlainObject(v)) && !isEmpty(v)) {
append(name, v)
} else {
fd.append(name, v)
}
}
}
append(rootKey, obj)
return fd
}
export default toFormData
mutation uploadFile($file: File!) {
upload(file: $file) {
url # Return whatever data you need
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment