I know this is a common issues, and I've made sure the app is sending the right data. I've even added logging to show that the fields are being populated correctly.
The one thing I noticed is the console.log I have inside parser.once('finish' () => {}) wasn't being called, which is where the "Missing multipart field" error should be coming from.? Any insight would be appreciated.
progressRequest - operations called {
? variables: { file: null, name: 'test' },
? query: 'mutation ($file: Upload!, $name: String!) {
' +
? ? ' ?createDocument(file: $file, name: $name) {
' +
? ? ' ? ?id
' +
? ? ' ? ?name
' +
? ? ' ? ?__typename
' +
? ? ' ?}
' +
? ? '}
'
}
processRequest - map called { '1': [ 'variables.file' ] }
processRequest - map entries [ [ '1', [ 'variables.file' ] ] ]
processRequest - map complete Map(1) {
? '1' => Upload {
? ? resolve: [Function (anonymous)],
? ? reject: [Function (anonymous)],
? ? promise: Promise { <pending> }
? }
}
processRequest - release Map(1) {
? '1' => Upload {
? ? resolve: [Function (anonymous)],
? ? reject: [Function (anonymous)],
? ? promise: Promise { [Object] },
? ? file: {
? ? ? filename: 'file.docx',
? ? ? mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
? ? ? encoding: '7bit',
? ? ? createReadStream: [Function: createReadStream]
? ? }
? }
}
BadRequestError: Missing multipart field ‘operations’ (https://github.com/jaydenseric/graphql-multipart-request-spec).
Client post has the following:
------WebKitFormBoundaryVcAmZ4u9BOEmAIVW
Content-Disposition: form-data; name="operations"
{"variables":{"file":null,"name":"test"},"query":"mutation ($file: Upload!, $name: String!) {
?createDocument(file: $file, name: $name) {
? ?id
? ?name
? ?__typename
?}
}
"}
------WebKitFormBoundaryVcAmZ4u9BOEmAIVW
Content-Disposition: form-data; name="map"
{"1":["variables.file"]}
------WebKitFormBoundaryVcAmZ4u9BOEmAIVW
Content-Disposition: form-data; name="1"; filename="file.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
------WebKitFormBoundaryVcAmZ4u9BOEmAIVW--??
Server Typescript:
import { FileUpload, GraphQLUpload } from "graphql-upload";
import { Mutation, Arg, Resolver } from "type-graphql";
import { Document } from "../Document";
@Resolver(Document)
export class DocumentResolver {
? ? @Mutation(() => Document)
? ? async createDocument(@Arg("name") name: string, @Arg("file", () => GraphQLUpload) file: FileUpload): Promise<Document> {
? ? ? ? console.warn(name, file);? ? ? ?
return null; // dont care about getting anything back as long as I see my console message
? ? };
}
Client Typescript:
import { Component } from "@angular/core";
import { Apollo, gql } from "apollo-angular";
@Component({
? selector: 'test-page',
? templateUrl: './test.html'
})
export class TestPageComponent {
? constructor(private apollo: Apollo) { }
? public onFileSelected(e: any): void {
? ? if (e.target.validity.valid) {
? ? ? this.serverResponse = {};
? ? ? this.serverResponseErr = {};
? ? ? let file = e.target.files[0];
? ? ? this.loadFileApollo(file);
? ? }
? }
? public loadFileApollo(file: File): void {
? ? const GRAPHQL_CREATE_TEMPLATE = `
? ? mutation($file: Upload!, $name: String!) {
? ? ? createDocument(file: $file, name: $name) {
? ? ? ? id,
? ? ? ? name
? ? ? }
? ? }`;
? ? //
? ? //var ti = { file: file };
? ? this.apollo.mutate<any>({
? ? ? mutation: gql(GRAPHQL_CREATE_TEMPLATE),
? ? ? variables: { file: file, name: "test" },
? ? ? context: {
? ? ? ? useMultipart: true
? ? ? }
? ? }).subscribe(x=> console.warn(x));
? }
}
HTML:
? <div>
? ? Click this button to select a file and immediately upload it to the server
? ? <input class="btn btn-primary" type="file" (change)="onFileSelected($event)"/>
? </div>
question from:
https://stackoverflow.com/questions/65887500/getting-the-infamous-400-error-from-graphql-when-uploading-a-file-debug-shows-d