Apollo is unable to upload the file within the class Object

I am currently working on a project where I need to upload files using a multipart request in Graphql. However, I have encountered an issue when creating an object of a class that contains a File - the file is not being uploaded. Strangely enough, if it is just an object without a class, the upload works perfectly fine.

For example, this code snippet works:

const upload = {
   file: new File()
};
apollo.mutate({
   mutation,
   variables:{
      fileParam: upload
   }
});

But this code snippet does not work:

class FileWrapper{
   constructor(public file: File){}
}
const upload = new FileWrapper(new File());
apollo.mutate({
   mutation,
   variables:{
      fileParam: upload
   }
});

To make it work with a class, you can try copying the object like so:

class FileWrapper{
   constructor(public file: File){}
}
const upload = new FileWrapper(new File());
apollo.mutate({
   mutation,
   variables:{
      fileParam: {...upload}
   }
});

The packages I am using for this project are:

    "nuxt": "^2.0.0",
    "@nuxtjs/apollo": "^4.0.1-rc.1",

One thing I tried was replacing the standard HttpLink with createUploadLink as shown below:

  return ApolloLink.from([
    mutationTrackerLink(getModule(MutationTrackState, ctx.store), providerName),
    queueLink,
    serializingLink,
    retryLink,
    authLink,
    createUploadLink({
      uri: `${endpoint}/graphql`,
    }),
  ]);

I also attempted to remove other links but ended up with the same result.

Answer №1

After thorough investigation, I identified the root cause in the package: https://github.com/jaydenseric/extract-files. It seems that the code snippet checks for object.constructor === Object, which fails to traverse deeper when dealing with objects instantiated from a class.

To address this issue, I implemented a custom function that transforms class-based objects into anonymous objects. The basis of this function was borrowed from a StackOverflow post (regrettably, I can't recall the exact source) and then customized to fit my requirements.

public static copyToAnonymusObject(obj: any) {
    let copy: any;

    // Handle basic types, null, or undefined
    if (obj === null || typeof obj !== 'object') return obj;

    // Treat File objects
    if (obj instanceof File) {
      return obj;
    }

    // Manage Date objects
    if (obj instanceof Date) {
      copy = new Date();
      copy.setTime(obj.getTime());
      return copy;
    }

    // Process Arrays
    if (Array.isArray(obj)) {
      copy = [];
      for (let i = 0, len = obj.length; i < len; i++) {
        copy[i] = this.copyToAnonymusObject(obj[i]);
      }
      return copy;
    }

    // Address Objects
    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.");
  }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What steps should I take to address the issue of sanitizing a potentially harmful URL value that contains a

I've encountered a URL sanitization error in Angular and despite researching various solutions, I have been unable to implement any of them successfully in my specific case. Hence, I am reaching out for assistance. Below is the function causing the i ...

Strange behavior detected in TypeScript generic function when using a class as the generic parameter

class Class { } const f0 = <T extends typeof Class> (c:T): T => { return c } const call0 = f0 (Class) //ok const f1 = <T extends typeof Class> (c:T): T => { const a = new c() return a //TS2322: Type 'Class' is not assigna ...

Difficulty with Iterating through Items in Angular HTML with *ngFor

Having an issue with *ngFor. It seems like the index in my tab object "joueurClassement" is not in the correct number sequence. The picture below illustrates this problem, where it works fine when the indexes are 0,1,2,3,4. In my HTML => <tbody ...

Angular is unable to fetch the chosen option from a dropdown selection

Recently, I encountered an issue with a module form that appears as a pop-up. Within this form, users can input data required to create a new object of a specific class. One field allows users to select a ventilation zone for the new room object being crea ...

The property 'x' is not found on 'Reel' type in this context

Creating a custom class extending Container in PIXI.js: export class CustomContainer extends Container { constructor(width: number, height: number) { super(); var sprite: Sprite = Sprite.fromImage("assets/images/elephant.png"); ...

Ways to invoke the function in a separate component

How can I use ViewChild to call a method in a different component? I have a method in the piechart component that I want to access from the app component using ViewChild. In my piechart.component.ts file: export class PiechartComponent { constructor() ...

Understanding the Typescript Type for a JSON Schema Object

When working with JSON-schema objects in typescript, is there a specific type that should be associated with them? I currently have a method within my class that validates whether its members adhere to the dynamic json schema schema. This is how I am doing ...

What is the process for connecting custom transformers to a compiler host?

My custom TypeScript watcher is set up like this: const compilerHost = typescript.createWatchCompilerHost(config.fileNames, config.options, typescript.sys, undefined, reportDiagnostic) typescript.createWatchProgram(compilerHost) I am trying to integrate ...

In TypeScript, inferring argument types

Here is the code snippet in question: type Inferred<T> = T extends (...args: (infer UnionType)[]) => any ? UnionType : never function f(first: 'first', second: 'second', bool: boolean) {} type T = Inferred<typeof f> // ...

Unable to delete event listeners from the browser's Document Object Model

Issue at hand involves two methods; one for initializing event listeners and the other for deleting them. Upon deletion, successful messages in the console confirm removal from the component's listener array. However, post-deletion, interactions with ...

Display Material Popup in Angular before user leaves the page

My goal is to display an Angular Material Dialog Box (Popup window) when the user clicks the Chrome Window Close button. The Dialog modal should prompt the user if they want to save changes or cancel. However, the modal only appears for a brief moment and ...

Implement Material-UI's built-in validation for form submission

I'm in the process of setting up a form with validation: import React from 'react'; import { useForm } from "react-hook-form"; import axios, {AxiosResponse} from "axios"; import {Box, Button, Container, Grid, Typography} ...

Exploring Angular (5) http client capabilities with the options to observe and specify the response type as 'blob'

Situation: I'm facing a challenge in downloading a binary file from a backend system that requires certain data to be posted as JSON-body. The goal is to save this file using File-Saver with the filename specified by the backend in the content-disposi ...

Utilizing ControlValueAccessor in various components

I am currently working on a component that implements the ControlValueAccessor interface, and I am facing some difficulties in understanding how to properly utilize it: // Angular Imports import { Component, OnInit, forwardRef, Output, EventEmitter, OnC ...

Saving the initial state value in a variable in Vue.js is a crucial step in managing and

My dilemma involves an object in the Vuex store containing data that I need to utilize within a component. I have successfully accessed the data using a getter in the component. However, I am facing a challenge in preserving the initial value of this objec ...

Exchange a TypeScript data type with a different one within an object

I am currently working with the following type definitions: type Target = number | undefined; type MyObject = { some: string; properties: string; id: Target; } I am trying to find a generic solution to replace instances of Target with number ...

When the *ngFor directive disrupts the CSS Grid Layout, resulting in all items being displayed in a single column

I am a beginner in the world of programming and web development. Currently, I am working on building my own personal website. My goal is to arrange boxes in a grid with 4 columns, similar to the layout you can find at this link: Each box represents an ob ...

Utilizing typescript to isolate specific functionality from a class without extending it

Imagine a scenario where I have a class with different areas of functionality: export class TreeTable extends someOtherClass { constructor(){ super.constructor(); } //========= area 1 of functionality ==== itemRightClick(){this.contex ...

Check if the <ion-content> in Angular Ionic has reached the bottom when scrolling

I'm in the process of developing a messaging app using Angular and Ionic. I want to trigger the scrollToBottom method only when it is scrolled to the very bottom. This way, if someone scrolls to the top to read old messages while their partner sends a ...

Checking the functionality of a feature with Jasmine framework in an Angular application

I am working on writing unit test cases and achieving code coverage for the code snippet below. Any advice on how to proceed? itemClick($event: any) { for (let obj of this.tocFiles) { let results = this.getchildren(obj, label); if (results) { conso ...