0

I've been following this guide https://medium.com/@p02diada/how-to-upload-files-with-ferry-graphql-and-flutter-34a2801d6a8a on how to upload a file using Ferry GraphQL. The only difference is that I'm using Dio's MultipartFile instead of http's MultipartFile. Whenever I try to call the mutation to upload, I'm always thrown a

`GqlException(LinkException(DioError [DioErrorType.other]: Converting object to an encodable object failed: Instance of 'MultipartFile`` error.

GraphQL file..
mutation UploadDocumentMutation($input: UploadDocumentInput!, $file: Upload!) {
    uploadDocument(input: $input, file: $file) {
        onboardingId,
    }
}

build.yaml file..
  gql_build|schema_builder:
    enabled: true
    options:
      schema: schemaLocation
      type_overrides:
        Upload:
          name: MultipartFile
          import: 'package:dio/dio.dart'
  gql_build|ast_builder:
    enabled: true
  gql_build|data_builder:
    enabled: true
    options:
      schema: schemaLocation
      type_overrides:
        Upload:
          name: MultipartFile
          import: 'package:dio/dio.dart'
  gql_build|var_builder:
    enabled: true
    options:
      schema: schemaLocation
      type_overrides:
        Upload:
          name: MultipartFile
          import: 'package:dio/dio.dart'
  gql_build|serializer_builder:
    enabled: true
    options:
      schema: schemaLocation
      custom_serializers:
        - import: 'package:path_to/upload_serializer.dart'
          name: UploadSerializer
  ferry_generator|req_builder:
    enabled: true
    options:
      schema: schemaLocation
      type_overrides:
        Upload:
          name: MultipartFile
          import: 'package:dio/dio.dart'

upload_serializer file..

import 'package:dio/dio.dart' show MultipartFile;

class UploadSerializer extends PrimitiveSerializer<MultipartFile> {
  @override
  MultipartFile deserialize(
    Serializers serializers,
    Object serialized, {
    FullType specifiedType = FullType.unspecified,
  }) {
    assert(serialized is List<int>, "FileSerializer expected 'Uint8List' but got ${serialized.runtimeType}");
    return MultipartFile.fromBytes(serialized as List<int>);
  }

  @override
  Object serialize(
    Serializers serializers,
    MultipartFile file, {
    FullType specifiedType = FullType.unspecified,
  }) =>
      file;

  @override
  Iterable<Type> get types => [MultipartFile];

  @override
  String get wireName => "Upload";
}

my upload method..

  Future<GUploadDocumentMutationData_uploadDocument?> uploadDocument(
UploadDocumentInput uploadDocumentInput,
MultipartFile multipartFile,
  ) async {
    final input = GUploadDocumentInputBuilder()
      ..onboardingId = uploadDocumentInput.onboardingId
      ..type = uploadDocumentInput.type.gType
      ..side = uploadDocumentInput.side.gType;

final GUploadDocumentMutationReq request = GUploadDocumentMutationReq(
  (b) => b
    ..vars.input.onboardingId = input.onboardingId
    ..vars.input.type = input.type
    ..vars.input.side = input.side
    ..vars.file = multipartFile,
);
try {
  final OperationResponse<GUploadDocumentMutationData, GUploadDocumentMutationVars> response =
      await client.request(request).first;

  final GUploadDocumentMutationData? responseData = processResponse(response);

  if (responseData != null) {
    return responseData.uploadDocument;
  } else {
    return null;
  }
}

My multipart file object also comes from this

final multipartFile = await MultipartFile.fromFile(
  Xfile.path,
);

Sorry for all of the code, I felt like a lot of it was necessary. Thank you.

Patttt
  • 51
  • 1
  • 3

1 Answers1

1

Did you try the same fix the article author used to resolve this problem?
The article recommends to simply not cache the result from the multipart queries like so:

final req = GUploadImageReq(
  (b) => b
    ..vars.input = input
    ..fetchPolicy = FetchPolicy.NoCache,
);
Flo
  • 11
  • 2