uploadMultipleFilesViaGraphQL method

Future<Map<String, dynamic>> uploadMultipleFilesViaGraphQL({
  1. required String mutationName,
  2. required Map<String, dynamic> variables,
  3. required Map<String, String> fileFields,
})

Implementation

Future<Map<String, dynamic>> uploadMultipleFilesViaGraphQL({
  required String mutationName,
  required Map<String, dynamic> variables,
  required Map<String, String> fileFields,
}) async {
  try {
    // Dynamic mutation based on mutationName
    String mutation;

    if (mutationName == "registerTenantUserWithMembership") {
      mutation = """
        mutation RegisterTenantUserWithMembership(\$input: RegisterTenantUserInput!) {
          registerTenantUserWithMembership(input: \$input) {
            success message token tenantUser { id }
          }
        }
      """;
    } else if (mutationName == "registerWithProductToken") {
      mutation = """
        mutation RegisterWithProductToken(\$input: ProductTokenRegistrationInput!) {
          registerWithProductToken(input: \$input) {
            success message token tenantUser { id }
          }
        }
      """;
    } else if (mutationName == "updateTenantUser") {
      mutation = """
        mutation UpdateTenantUser(\$input: UpdateTenantUserInput!) {
          updateTenantUser(input: \$input) {
            success
            message
            tenantUser {
              id
              firstName
              lastName
              phoneNumber
              location
              profile_Photo
              image
              video
              updatedAt
            }
          }
        }
      """;
    } else {
      return {'success': false, 'message': 'Unknown mutation: $mutationName'};
    }

    final map = <String, List<String>>{};
    final files = <MultipartFile>[];
    int index = 0;

    for (final entry in fileFields.entries) {
      final file = File(entry.value);
      if (!await file.exists()) {
        print(' File not found: ${entry.value}');
        continue;
      }

      final bytes = await file.readAsBytes();
      final fileName = entry.value.split('/').last;

      print(' Uploading file: $fileName (${bytes.length} bytes) as field: ${entry.key}');

      files.add(MultipartFile.fromBytes(
        bytes,
        filename: fileName,
        contentType: MediaType.parse(_getMimeType(fileName)),
      ));

      map["$index"] = ["variables.input.${entry.key}"];
      index++;
    }

    print(' File map: $map');

    final formData = FormData();

    // 1. First add operations
    formData.fields.add(MapEntry(
      "operations",
      jsonEncode({"query": mutation, "variables": variables}),
    ));

    // 2. Then add map
    formData.fields.add(MapEntry(
      "map",
      jsonEncode(map),
    ));

    // 3. Finally add files
    for (int i = 0; i < files.length; i++) {
      formData.files.add(MapEntry("$i", files[i]));
    }

    print(' Sending multipart request...');

    final response = await _dio.post(
      '/graphql',
      data: formData,
      options: Options(
        contentType: 'multipart/form-data',
        followRedirects: true,
      ),
    );

    print('Response received: ${response.data}');

    final json = response.data as Map<String, dynamic>;

    if (json['errors'] != null) {
      final errorMsg = json['errors'][0]['message'];
      print('GraphQL Error: $errorMsg');
      return {'success': false, 'message': errorMsg};
    }

    return json;
  } catch (e, stackTrace) {
    print(" Upload failed: $e");
    print("Stack trace: $stackTrace");
    return {'success': false, 'message': e.toString()};
  }
}