-
Notifications
You must be signed in to change notification settings - Fork 50
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
No UI example found #29
Comments
What do you mean by UI example? |
There is no client side code in the example only backend code is there. A React.JS implementation is missing in the example. |
This is a backend implementation for GraphQL multipart specification. There separate frontend repositories for different frameworks and libraries. Here is the repo for the specification: https://github.com/jaydenseric/graphql-multipart-request-spec/blob/master/readme.md. If you check the end of README, you will see different repos for frameworks / libraries for both client and server. I think it doesn’t make sense to show examples for frontend here because it is based on a specification written by a 3rd party. Plus, If React example is added, Angular and Vue examples should also be added. The specification’s repo has all the necessary information for different tools. |
for those who are still struggling with this (as I did) here is a code that may help import { print } from 'graphql/language/printer';
const createOptions = (opts) => {
const formData = new FormData();
opts.variables.files.forEach((file, i) => {
formData.append('map', `{"${i}": ["variables.files.${i}"] }`);
formData.append(`${i}`, file, file.name);
});
const files_null = opts.variables.files.map(() => null) // one null for each file, e.g. "null,null,null"
const variables = {...opts.variables}
variables.files = files_null
//see https://stackoverflow.com/questions/57490569/import-graphql-query-gql-file-into-plain-javascript-and-run-an-axios-call
const value = {
query: print(opts.query),
variables: variables
}
formData.append('operations', JSON.stringify(value).replace(/\\n/g, ''))
return {
method: 'POST',
credentials: 'include',
body: formData,
}
}
const uploadFile = (opts) => {
console.assert(opts.variables.files.length > 0, 'files is empty');
return fetch(
`${process.env.NEXT_PUBLIC_BACKEND}upload/`,
createOptions(opts)
);
};
// const [uploadFiles, { status }] = useUploadFiles()
export default uploadFile; Mutation export const UPLOAD_FILES = gql`
mutation uploadFiles($files: [Upload]!) {
uploadFiles(files: $files) {
ok
urls {
url
name
}
}
}
` Call: just use an input type="file" and call uploadFIle({query: UPLOAD_FILES, variables: { files: [e.target.files[0]] }} |
@luiskarlos I am doing the same thing, but getting an empty dict on the server (Django/graphene) side. Also in that last line you posted, it should be 'mutation: UPLOAD_FILES' rather than 'query: UPLOAD_FILES', right?
And I am calling this method like this:
onFileUpload is invoked from an 'input type="file" HTML element. I have printed (console.log) the myFile variable in onFileUpload handler function and the 'agFile' variable in the uploadFile service function right before the mutation call, and they indeed are file objects. But for whatever reason, when apollo picks it up it makes it into an empty dict. Any help is much appreciated. |
Also adding that the above mutation is working from the Altair graphql client. |
@boomdizz This is the code I am using right now, my backend is with python so I am not sure how it will work with js: this is a utility uploadFile.js import { print } from 'graphql/language/printer';
const createOptions = (opts) => {
const formData = new FormData();
opts.variables.files.forEach((file, i) => {
formData.append('map', `{"${i}": ["variables.files.${i}"] }`);
formData.append(`${i}`, file, file.name);
});
const files_null = opts.variables.files.map(() => null); // one null for each file, e.g. "null,null,null"
const variables = { ...opts.variables };
variables.files = files_null;
//see https://stackoverflow.com/questions/57490569/import-graphql-query-gql-file-into-plain-javascript-and-run-an-axios-call
const value = {
query: print(opts.query),
variables: variables,
};
formData.append('operations', JSON.stringify(value).replace(/\\n/g, ''));
return {
method: 'POST',
credentials: 'include',
body: formData,
};
};
const uploadFile = (opts) => {
console.assert(opts.variables.files.length > 0, 'files is empty');
return fetch(
`${process.env.NEXT_PUBLIC_BACKEND}upload/`,
createOptions(opts)
);
};
export default uploadFile; This a hook import { useEffect, useState } from 'react';
import uploadFile from '../utils/uploadFile';
const useUpload = (query) => {
const [options, upload] = useState({ variables: {} });
const [status, setStatus] = useState({
uploading: false,
success: false,
error: false,
data: null,
message: null,
});
const updateStatus = (uploading, success, error, data, message) =>
setStatus({ uploading, success, error, data, message });
useEffect(() => {
if (options.variables?.files?.length) {
updateStatus(true, false, false, null, 'Uploading...');
uploadFile({ query, ...options })
.then((result) => {
return result.json();
})
.then((result) => {
if (result.errors) {
throw new Error(result.errors[0].message);
}
updateStatus(
false,
true,
false,
result.data,
'Files Uploaded Successfully'
);
})
.catch((error) => {
updateStatus(false, false, true, error.message);
console.log('error', error);
});
}
}, [options]);
return [upload, { ...status }];
};
// const [uploadFiles, { status }] = useUploadFiles()
export default useUpload; This is the query: export const UPLOAD_FILES = gql`
mutation uploadFiles($files: [Upload]!) {
uploadFiles(files: $files) {
ok
}
}
`; This is my mutation: class UploadFilesMutation(graphene.Mutation):
class Arguments:
files = graphene.List(Upload)
file = graphene.Field(FileType)
def mutate(self, info, files, **kwargs):
rf = StorageSystem.save_file(info.context.user, files[0], public=False)
return UploadFilesMutation(document=document) |
I was able to finally get it to work in the Angular/Apollo environment. I have it documented as the answer to my own question on Stackoverflow |
We are trying to use this in our project not able to create a ui not even properly test.we need an documentation/ examples including ui
The text was updated successfully, but these errors were encountered: