In my project I try to upload files in a multipart request via Graphql. The problem is, when I create an object of a class, which contains a File, the file is not uploaded. When it is just an Object without a class it is working.
This is working:
const upload = {
file: new File()
};
apollo.mutate({
mutation,
variables:{
fileParam: upload
}
});
This is not working:
class FileWrapper{
constructor(public file: File){}
}
const upload = new FileWrapper(new File());
apollo.mutate({
mutation,
variables:{
fileParam: upload
}
});
This is working:
class FileWrapper{
constructor(public file: File){}
}
const upload = new FileWrapper(new File());
apollo.mutate({
mutation,
variables:{
fileParam: {...upload}
}
});
Packages I am using:
"nuxt": "^2.0.0",
"@nuxtjs/apollo": "^4.0.1-rc.1",
I replaced the standard HttpLink with createUploadLink like so:
return ApolloLink.from([
mutationTrackerLink(getModule(MutationTrackState, ctx.store), providerName),
queueLink,
serializingLink,
retryLink,
authLink,
createUploadLink({
uri: `${endpoint}/graphql`,
}),
]);
I tried to remove all the other links, but with the same result.
I traced the problem back to the package: https://github.com/jaydenseric/extract-files
It checks if object.constructor === Object
. This is not the case when you have an object of a class and therefore it doesn't look deeper into the object.
For now I solved it with this function which makes the object of a class to an anonymous object. I mostly copied this function form another StackOverflow post (unfortunatley I forgot which one) and modified it slightly.
public static copyToAnonymusObject(obj: any) {
let copy: any;
// Handle the 3 simple types, and null or undefined
if (obj === null || typeof obj !== 'object') return obj;
// Handle File
if (obj instanceof File) {
return obj;
}
// Handle Date
if (obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// Handle Array
if (Array.isArray(obj)) {
copy = [];
for (let i = 0, len = obj.length; i < len; i++) {
copy[i] = this.copyToAnonymusObject(obj[i]);
}
return copy;
}
// Handle Object
if (obj instanceof Object) {
copy = {};
Object.keys(obj).forEach((key) => {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
copy[key] = this.copyToAnonymusObject(obj[key]);
}
});
return copy;
}
throw new Error("Unable to copy obj! Its type isn't supported.");
}