Encountering TypeScript errors with React-Apollo when using GraphQL to pass props to a higher order component

I've encountered some challenges while attempting to link a React class component with my local Apollo cache data.

Following the guidelines outlined here, I have run into issues where VSCode and Webpack are generating errors when I try to access data using this syntax: this.props.data.playing. Despite the error prompts, the browser displays the correct data. However, if I access the data as this.props.data.data.playing, the typecheck passes but triggers an error in the browser console (

Cannot read property 'playing' of undefined
). It seems like there might be a type definition error, but the exact source of the problem eludes me.

I would like to clarify that all NPM packages have been updated.

type AudioData = {
  bpm: number;
  beatsPerBar: number;
  playing: boolean;
  metronomeSound: string;
  playPosition: number;
  playStartTime: number;
};

type Response = {
  data: AudioData;
};

class ConnectedWorkspaceAudio extends React.Component<
  ChildProps<{}, Response>
> {
  _context: AudioContext;
  _scheduler: Scheduler;
  _recorder: Recorder;

  constructor(props: ChildProps<{}, Response>) {
    super(props);
  }

  componentDidMount(): void {
    /***/
  }

  componentDidUpdate(prevProps: ChildProps<{}, Response>): void {
    console.log(this.props.data.playing); // Fails type check, prints correctly in browser.
    if (this.props.data.data) {
      if (this.props.data.data.playing && !prevProps.data.data.playing) { // Passes type check, gives console error in browser.
        useApolloClient().writeData({ data: { playing: true } });
      }
      if (!this.props.data.data.playing && prevProps.data.data.playing) {
        useApolloClient().writeData({ data: { playing: false } });
      }
    }
  }

  /** Additional methods such as render() have been omitted for brevity. */
}


const WORKSPACE_AUDIO_QUERY = gql`
  query AudioState {
    bpm @client
    beatsPerBar @client
    playing @client
    metronomeSound @client
    playPosition @client
    playStartTime @client
  }
`;

const WorkspaceAudio = graphql<{}, Response>(WORKSPACE_AUDIO_QUERY)(
  ConnectedWorkspaceAudio
);

export { WorkspaceAudio };

Answer №1

Typically, this error occurs when attempting to access data that is not yet ready. This often happens in the render() function when the required data has not been fetched yet.

To fix this issue, add a console log statement after if (this.props.data.data) { but make sure the logging argument is correct:

console.log(this.props.data.data.playing);
. The response object is named data, which can be a bit misleading at first glance.

Answer №2

An alternative approach was taken by refraining from encapsulating the AudioData type within a Response, even though this is commonly done according to the documentation. Modifications were made to the following sections:

class EnhancedWorkspaceAudio extends React.Component<
  Props<{}, AudioData>
{
...

const WorkspaceAudio = graphql<{}, AudioData>(WORKSPACE_AUDIO_QUERY)(
  EnhancedWorkspaceAudio
);

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

Argument not accepted in JavaScript

Currently, I am encountering a unique error message while working with a complex function that iterates through elements in my JavaScript onSuccess event. The error I am seeing is: exception encountered : {"message": "Invalid argument.", "description": " ...

Exploring ways to cycle through an array of objects during a jQuery ajax request

When making a jQuery ajax call to iterate over an API response, I am encountering the issue of receiving undefined data for all elements. Can someone guide me on how to properly iterate through an array of objects in jQuery? I am new to handling iteration ...

Select a random class from an array of classes in JavaScript

I have a collection of Classes: possibleEnemies: [ Slime, (currently only one available) ], I am trying to randomly pick one of them and assign it to a variable like this (all classes are derived from the Enemy class): this.enemy = new this.possibleEn ...

"Effortlessly move elements with HTML5 drag and drop functionality from either direction

I'm working on an application that requires Html5 Drag and Drop functionality, which is currently functioning well. However, in the app, there may be instances where a dropped item is no longer needed and I want to allow users to re-drag and drop it b ...

Refining strings to enum keys in TypeScript

Is there a method to refine a string to match an enum key in TypeScript without needing to re-cast it? enum SupportedShapes { circle = 'circle', triangle = 'triangle', square = 'square', } declare const square: string; ...

Storing data with ElectronJS

I am currently working on an Electron JS and React JS offline application. One of the initial steps in my launch process involves loading a large file that is over 1 GB in size and cannot be divided. This causes a delay of approximately 50-60 seconds whi ...

How can you merge the class attribute with the ng-class directive based on boolean values?

In my custom directive's link function, I have the following code that dynamically generates a map using d3... map.append("g") .selectAll("path") .data(topojson.feature(counties, counties.objects.counties).features) .enter() .append("path") .attr("d" ...

Error in Typescript SPFx: The property 'news' is not found in the type 'Readonly<{}>'

Currently, I am working on developing a spfx react component to showcase an RSS feed in the browser. My prototype is functional in a test environment, however, as spfx utilizes TypeScript, I am encountering a type error that I am unsure how to resolve. Rs ...

The module in Node.js is unable to be loaded

Dealing with a common problem here. Despite trying to reinstall npm, deleting node_modules files and package-lock.json, the issue persists. The console output is as follows: node:internal/modules/cjs/loader:1080 throw err; ^ Error: Cannot find module &apo ...

Is there a way to postpone these animations without relying on setTimeout?

As I develop a single-page website, my goal is to smoothly transition between sections by first animating out the current content and then animating in the new content. Currently, I have achieved this using setTimeout(), where I animate out the current con ...

Update the content of the widget

Currently, I am utilizing the following script to display NBA standings: <script type="text/javascript" src="https://widgets.sports-reference.com/wg.fcgi?script=bbr_standings&amp;params=bbr_standings_conf:E,bbr_standings_css:1&amp"></sc ...

Disappearing input field in DateTimePicker Bootstrap when blurred

Currently, I am utilizing the Bootstrap DateTimePicker plugin to enable users to select a specific date and time. The plugin functions well with one minor issue - whenever the user clicks outside or loses focus on the calendar box, both the box itself and ...

Ways to utilize built-in features from a Java library that has been incorporated

I have embarked on a project to create a Nativescript wrapper for a Java library in order to harness its functionalities for a Nativescript application. Despite the lack of detailed articles on this topic, I have decided to turn this into a plugin wrapper ...

Alerts are essential for the proper functioning of the AJAX function. Without them

As I incorporate a substantial amount of AJAX with XML Http Requests on my website, I encounter a peculiar issue with a few random AJAX calls. There seems to be an execution problem within my JavaScript code in the onreadystatechange function where certain ...

The problem with Ajax POST is occurring in Firefox and Chrome, but not in IE8

I am encountering an issue with the code snippet provided below. Upon executing it in Internet Explorer 8, I receive an alert when the call is successful. However, this behavior does not occur in Firefox and Chrome. In other words, there is no alert disp ...

What is the best way to convert JavaScript to JSON in Python programming?

I encountered a situation where I have an HTML page that contains a lengthy product list, making it too large for me to upload. The products are stored within the script section of the page, specifically in one variable. Initially, I mistook this data for ...

Material-UI exclusively incorporates specific components

Is there a way to include Material UI dialogs in my project without having to install the full Material UI library? I only need the dialogs component and don't want any other components included. Any suggestions or help on how to achieve this would be ...

Upgrade to the latest version of MaterialUI - V4

After attempting to upgrade materialUI/core from version 3.9.3 to 4.4.1 and materialUI/icons from version 3.0.2 to 4.4.1, I encountered the following error: Error: TypeError: styles_1.createGenerateClassName is not a function I am currently importing crea ...

Node.js: Extract the object's name and value that are sent from the frontend

I'm in the process of creating a microservice using nodejs. The request is returning the following JSON. { "distCd": "abcd", "distName": "parentLife Distributor (TOD)", "stateCd": "", "subdistInd": false, "maindistInd": true ...

Effortless implementation of list loading with images and text in the Ionic 2 framework

Can someone provide guidance on creating a lazy loading list with both images and text? I understand that each image in the list will require a separate http request to download from the server. Should caching be implemented for these image downloads? Addi ...