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

Execute JavaScript function after completion of CSS animation using jQuery

I'm working on an accordion feature that uses CSS animation to expand the clicked item. The expansion is triggered by li:target. However, I'm facing an issue where when clicking on an item, the scroll position doesn't align correctly with t ...

Encountering a parsing issue: an unexpected token was found, expecting "," instead

I'm encountering a Parsing error that states: Unexpected token, expected ",". I've been unable to pinpoint where the missing "," is located. Please refer to the image below for the exact line of the error. const cartSlice = createSlice({ name ...

The D3 data format allows for creating interactive sunburst charts that can be easily zoom

My data is structured similarly to flare.json as shown in this example: I'm curious about the function used by the d3 zoomable chart to format the data in this way. The original structure in flare.json looks like this: { name: "stuff", childr ...

Modifying the initialValues prop on a Formik Form does not reflect changes in the input values

Utilizing a Formik form with forward refs in the following manner Form.js import React from "react"; import FormikWithRef from "./FormikWithRef"; const Form = ({ formRef, children, initialValues, validationSchema, onSubmit }) ...

Automatically submitting a form in React.js based on certain conditions being met

Does anyone have experience with React login and register form buttons that trigger Redux actions? I'm facing an issue where both actions are being dispatched at the same time when certain conditions are met. Here is my code snippet: const LoginPage ...

Struggles with updating app.component.ts in both @angular/router and nativescript-angular/router versions

I have been attempting to update my NativeScript application, and I am facing challenges with the new routing system introduced in the latest Angular upgrade. In my package.json file, my dependency was: "@angular/router": "3.0.0-beta.2" After the upg ...

During rendering, the instance attempts to reference the "handleSelect" property or method which is not defined

I've incorporated the Element-UI NavMenu component into my web application to create a navigation bar using Vue.JS with TypeScript. In order to achieve this, I have created a Vue component within a directory called "navBar," which contains the follow ...

Improved method for categorizing items within an Array

Currently working on developing a CRUD API for a post-processing tool that deals with data structured like: { _date: '3/19/2021', monitor: 'metric1', project: 'bluejays', id1: 'test-pmon-2', voltageConditio ...

Securing Your ExpressJs API Files from Prying Eyes in Developer Tools

Typically, when I utilize developer tools in Google and choose to open an API file in a new tab, I am able to view the data as illustrated below. However, there are occasions where upon attempting the same action on certain websites, a security precaution ...

Using Jquery to iterate through a dynamic list of elements

Currently, I am exploring the idea of creating a forEach loop that can handle an unspecified number of elements. The goal is to randomly select one element, perform XYZ actions on it, make it visible, and then eliminate it from consideration. This process ...

Performing asynchronous ajax calls with jQuery

Here is some code I have that involves a list and making an ajax call for each element in the list: util.testMethod = function(list) { var map = new Map(); list.forEach(function(data) { $.ajax({ ...

Can you explain the contrast between 'depict' and 'examine' when using Jest?

I am currently diving into the world of unit testing in Vue.js with Jest. One question that keeps popping up is when to use describe and when to use test ? TodoApp.vue Component : <template> <div> <h1>TodoApp Componenent</h1> ...

Inversify is a proven method for effectively injecting dependencies into a multitude of domain classes

Struggling to navigate dependencies and injections in a TypeScript-built rest web service without relying heavily on inversify for my domain classes, in line with the dependency inversion principle. Here's an overview of the project structure: core/ ...

By utilizing ngOnInit() over a constructor, the @Input() property remains uninitialized

If this design is considered terrible, I am more than willing to make changes. Within my index.html, in the body section, I have: <month [year]="2016" [monthOfYear]="4">Loading...</month> The contents of month.component.ts are as follows: i ...

Adding markers to a map in Angular 2 using ngOnInit after initialization

Embarking on my Angular journey by creating a sample app incorporating GoogleMaps. import { Component, Input, OnInit, Inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { FormControl } from '@ ...

I am looking to retrieve products based on category alone, category and model together, or simply obtain all products in one go. At the moment, I am utilizing three distinct endpoints

I have 3 endpoints on my backend that fetch products based on certain criteria. I'm considering whether to refactor the logic and combine them into a single endpoint/function. Currently, my routes are structured as follows: router.get('/products& ...

Navigational elements, drawers, and flexible designs in Material-UI

I'm working on implementing a rechart in a component, but I've encountered an issue related to a flex tag. This is causing some problems as I don't have enough knowledge about CSS to find a workaround. In my nav style, I have display: flex, ...

Utilize the same variable within a React functional component across multiple components

Within a React functional component, I am utilizing the following constant: const superHeroPowers = [ { name: 'Superman', status: superManPowerList }, { name: 'Batman', status: batmanPowerList }, { name: 'Wonder Woman&a ...

What could be the reason for the styled-jsx not applying the keyframe animation?

When attempting to add the animation separately without any conditions, the transition fails to be applied. Changing the quotation marks to backticks for the animation property also did not work. Is there a way to apply both the animation when clicked is ...

Is there an automatic bottom padding feature?

Currently, I am facing a challenge in fitting the loader into the container without it being overridden by the browser. Using padding-bottom is not an ideal solution as it results in the loader appearing un-resized and unprofessional. Any suggestions or co ...