-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Modern] Lacking Classic mutation's getFiles() equivalent #1844
Comments
I believe you can do something like this: function fetchQuery(operation, variables, cacheConfig, uploadables) {
let init;
// https://github.com/facebook/relay/blob/master/packages/react-relay/classic/network-layer/default/RelayDefaultNetworkLayer.js#L97
if (uploadables) {
if (!window.FormData) {
throw new Error("Uploading files without `FormData` not supported.");
}
const formData = new FormData();
formData.append("query", operation.text);
formData.append("variables", JSON.stringify(variables));
for (const uploadable in uploadables) {
if (Object.prototype.hasOwnProperty.call(uploadables, uploadable)) {
formData.append(uploadable, uploadables[uploadable]);
}
}
init = {
method: "POST",
body: formData
};
} else {
init = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
query: operation.text,
variables
})
};
}
return fetch('/graphql', init).then(response => response.json());
} |
Awesome. Let me try it out and will come back with my findings. |
@trongthanh can we close this? |
@sibelius Yes, please. Here's a complete example of the relay modern environment in case anyone need: // relay-environment.js
import {
Environment,
Network,
RecordSource,
Store,
} from 'relay-runtime';
import ErrorHandler from './helpers/ErrorHandler';
import config from './config';
import auth from './auth';
function fetchQuery(operation, variables, cacheConfig, uploadables) {
const request = {
method: 'POST',
headers: {
Authorization: `JWT ${auth.getToken()}`,
},
};
if (uploadables) {
if (!window.FormData) {
throw new Error('Uploading files without `FormData` not supported.');
}
const formData = new FormData();
formData.append('query', operation.text);
formData.append('variables', JSON.stringify(variables));
Object.keys(uploadables).forEach(key => {
if (Object.prototype.hasOwnProperty.call(uploadables, key)) {
formData.append(key, uploadables[key]);
}
});
request.body = formData;
} else {
request.headers['Content-Type'] = 'application/json';
request.body = JSON.stringify({
query: operation.text,
variables,
});
}
return fetch(config.GRAPHQL_ENDPOINT, request)
.then(response => {
if (response.status === 200) {
return response.json();
}
// HTTP errors
// TODO: NOT sure what to do here yet
return response.json();
})
.catch(error => {
console.log(error);
});
}
const source = new RecordSource();
const store = new Store(source);
// singleton Environment
export default new Environment({
// network: networkLayer,
// handlerProvider,
network: Network.create(fetchQuery),
store,
}); Here's a sample mutation with : import { commitMutation, graphql } from 'react-relay';
import environment from '../../relay-environment';
const mutation = graphql`
mutation createOnePostMutation ($input: RelayCreateOnePostInput!) {
postCreate(input: $input) {
record {
id
title
content
}
}
}
`;
// import createOnePostMutation from 'createOnePostMutation'
export default ({ post, file, onCompleted, onError }) => {
const variables = {
input: {
record: {
title: post.title,
content: post.content,
authorId: post.authorId,
}
},
};
let uploadables;
if (file) {
uploadables = {
file,
};
}
commitMutation(environment, {
mutation,
variables,
uploadables,
onCompleted,
onError,
});
}; |
Thanks for example! |
Is it possible to do chunk upload with relay environment ? |
you can do this inside your network layer |
Did anyone tried this solution in |
I am using this function on React Native and it seems to be working. Hope it helps. It follows graphql-multipart-request-spec. const fetchRelay: FetchFunction = async (
request,
variables,
cacheConfig,
uploadables
) => {
const requestInit: RequestInit = {
method: 'POST',
credentials: 'include',
headers: {},
};
if (uploadables) {
if (!window.FormData) {
throw new Error('Uploading files without `FormData` not supported.');
}
const formData = new FormData();
formData.append(
'operations',
JSON.stringify({
query: request.text,
variables: variables,
})
);
const uploadableMap: {
[key: string]: string[];
} = {};
Object.keys(uploadables).forEach((key) => {
if (Object.prototype.hasOwnProperty.call(uploadables, key)) {
uploadableMap[key] = [`variables.${key}`];
}
});
formData.append('map', JSON.stringify(uploadableMap));
Object.keys(uploadables).forEach((key) => {
if (Object.prototype.hasOwnProperty.call(uploadables, key)) {
formData.append(key, uploadables[key]);
}
});
requestInit.body = formData;
} else {
requestInit.headers['Content-Type'] = 'application/json';
requestInit.body = JSON.stringify({
query: request.text,
variables,
});
}
const response = await fetch(API_URL, requestInit);
// Get the response as JSON
const json = await response.json();
// GraphQL returns exceptions (for example, a missing required variable) in the "errors"
// property of the response. If any exceptions occurred when processing the request,
// throw an error to indicate to the developer what went wrong.
if (Array.isArray(json.errors)) {
console.log(json.errors);
throw new Error(
`Error fetching GraphQL query '${
request.name
}' with variables '${JSON.stringify(variables)}': ${JSON.stringify(
json.errors
)}`
);
}
// Otherwise, return the full payload.
return json;
}; |
The documentation for Mutations of Relay Modern didn't mention how to attach files to upload with the mutation similarly to Classic mutation's getFiles().
Is this feature not available yet in Modern (I'm using react-relay@1.0.0) ? Or the feature lacks documentation?
The text was updated successfully, but these errors were encountered: