javascript – Error with componentDid mount when setting value from api call response

I have a disableButton: boolean; and want to set it’s value based on the response from this GET:

async getDocStatus(policy: string): Promise<boolean> {
    return await ApiService.getData(this.apiUrl + policy + this.myEndpoint).then(
        (response) => response.data
    );
}

I’d like this to be done when my page loads so have added the call to my componentDidMount:

componentDidMount() {
   const queryString = require('query-string');
   const parsed = queryString.parse(location.search);
   return this.reissueCertService.getDocStatus(parsed.pol).then(response => {
      this.setState({disableButton: response});
   }).catch((error) => {
         this.loggingService.logError('Error returning Docs ' + error);
   });
}

My problem is that when I load my page I get this error and I’m not really sure what it’s telling me or how to fix it. Can anybody advise?

TypeError: Cannot read properties of undefined (reading ‘getDocStatus’) CertificateDisclaimer../src/components/certificate/Certificate.tsx.Certificate.componentDidMount C:/git/ui.myui/src/components/certificate/Certificate.tsx:38 35 | componentDidMount() { 36 | const queryString = require(‘query-string’); 37 | const parsed = queryString.parse(location.search); 38 | this.reissueService.getDocStatus(parsed.policy).then(response => { 40 | this.setState({disableButton: response}}); 41 | }).catch((error) => { View compiled ▼ 19 stack frames were expanded. commitLifeCycles C:/git/ui.myui/node_modules/react-dom/cjs/react-dom.development.js:19814 commitLayoutEffects C:/git/ui.myui/node_modules/react-dom/cjs/react-dom .development.js:22803 HTMLUnknownElement.callCallback C:/git/ui.myui/node_modules/react-dom/cjs/react-dom.development.js:188 invokeGuardedCallbackDev C:/git/ui.myui/node_modules/react-dom /cjs/react-dom.development.js:237 invokeGuardedCallback C:/git/ui.myui/node_modules/react-dom/cjs/react-dom.development.js:292 commitRootImpl C:/git/ui.myui/node_modules /react-dom/cjs/react-dom.development.js:22541 unstable_runWithPriority C:/git/ui.myui/node_modules/scheduler/cjs/scheduler.development.js:653 runWithPriority$1 C:/git/ui.myui/ node_modules/react-dom/cjs/react-dom.development.js:11039 commitRoot C:/git/ui.myui/node_modules/react-dom/cjs/react-dom .development.js:22381 finishSyncRender C:/git/ui.myui/node_modules/react-dom/cjs/react-dom.development.js:21807 performSyncWorkOnRoot C:/git/ui.myui/node_modules/react-dom/cjs /react-dom.development.js:21793 (anonymous function) C:/git/ui.myui/node_modules/react-dom/cjs/react-dom.development.js:11089 unstable_runWithPriority C:/git/ui.myui/ node_modules/scheduler/cjs/scheduler.development.js:653 runWithPriority$1 C:/git/ui.myui/node_modules/react-dom/cjs/react-dom.development.js:11039 flushSyncCallbackQueueImpl C:/git/ui. /node_modules/react-dom/cjs/react-dom.development.js:11084 flushSyncCallbackQueue C:/git/ui.myui/node_modules/react-dom/cjs/react-dom.development.js:11072UpdateOnFiber C:/git schedule /ui.myui/node_modules/react-dom/cjs/react-dom.development.js:21199 enqueueSetState C:/git/ui.myui/node_modules/react-dom/cjs/react-dom.development.js:12639 Document ../node_modules/react/cjs/react.development.js.Component.setState C:/git/ui.myui/node_modules/react/cjs/react.development.js :471 ▲ 19 stack frames were expanded. (anonymous function) C:/git/ui.myui/src/containers/document/Document.tsx:37 34 | const queryString = require(‘query-string’); 35 | const parsed = queryString.parse(location.search); 36 | return this.listingService.getDocs(parsed.policy).then(docs => { 37 | this.setState({ isLoading: false, docs }); 38 | return docs; 39 | }).catch((error) => { 40 | this.loggingService.logError(‘Error returning Docs ‘ + error); View compiled This screen is visible only in development. It will not appear if the app crashes in production. Open your browser’s developer console to further inspect this error.

This is my component class:

import * as React from 'react';
import './Certificate.css';
import { PackRow } from '../../services/DocService/DocService';
import { LoggingService } from '../../services/logging/LoggingService';
import Cookies from 'js-cookie';
import crypto from 'crypto';
import { Reissue } from '../reissue/Reissue';
import { Button } from '@digital/react-avis-atom';
import { ReissueService } from 'src/services/ReissueService/ReissueService';

interface Props {
  pol: string;
  triggerReload: () => void;
  packs: PackRow[];
}

interface State {
   disableButton: boolean;
   showPrompt: boolean;
}

export class Certificate extends React.Component<Props, State> {
  loggingService: LoggingService;
  reissueCertService: ReissueService;

  constructor(props: Props) {
    super(props);
    this.loggingService = new LoggingService();
    this.state = {
      disableButton: false,
      showPrompt: false
    };
  }

  componentDidMount() {
      const queryString = require('query-string');
      const parsed = queryString.parse(location.search);
      return this.reissueCertService.getDocStatus(parsed.pol).then(response => {
         this.setState({disableButton: response});
      }).catch((error) => {
          this.loggingService.logError('Error returning Docs ' + error);
      });
  }

  onAgreement = (pol: string) => () => {
    if (this.consentGiven(this.props.pol)) {
       return;
    }

    this.loggingService.logCertAndDiscAgreement(
      'Uploading cert and disc agreement',
      pol
    );
    
    let content="";
    this.props.packs.forEach(pack => {
       pack.docDisplay.forEach(docRow => {
          if (docRow.docName === 'Certificate and Disc') {  
             content += this.getDocumentId(docRow.docUrl) + ';';
          }
       });
    });
    const ref = crypto.createHash('sha1').update(pol).digest('hex');
    Cookies.set('CONSENT_' + ref, content, { expires: 365,  path: '' });
    this.props.triggerReload();
  }
  
  consentGiven = (pol: string) => {
     const ref = crypto.createHash('sha1').update(pol).digest('hex');
     const consentedDocs = Cookies.get('CONSENT_' + ref) || null;
     if (consentedDocs === null) {
       return false;
     }
 
     let consent = true;
     this.props.packs.forEach(pack => {
        pack.docDisplay.forEach(docRow => {
        if (
           docRow.docName === 'Certificate and Disc'  
           && !consentedDocs.includes(this.getDocumentId(docRow.docUrl))) {
              consent = false;
           }
        });
     });
     return consent;         
  }
  
  certDiscCount = () => {
     let count = 0;
     this.props.packs.forEach(pack => {
        pack.docDisplay.forEach(docRow => {
           if (docRow.docName === 'Cert and Disc') {
              count++;
           }
        });
     });
     return count;       
  }
  
  getDocumentId = (docUrl: string) => {
     const docPath = docUrl.match(//documents/(.+?)//g);
     const docPathElements = docPath !== null ? docPath[0].split("https://stackoverflow.com/") : null;
     return docPathElements !== null && docPathElements.length > 3 ? docPathElements[2] : '';        
  }
  
  consentBox = (pol: string) => {
     return this.consentGiven(pol) ? 'consent-cell--agreement consent-cell--agreed' : 'consent-cell--agreement';
  }
 
  showReissue = () => {
   this.setState({ showPrompt: true });
  }
 
  hideReissue = () => {
   this.setState({ showPrompt: false });
  }
 
  disableButton = () => {
   this.setState({ disableButton: true });
  }

  render() {
    const { pol } = this.props;
    if (this.certDiscCount() === 0) {
       return ('');
    }

    return (
      <table className="consent-table">
        <thead>
          <tr>
            <th colSpan={2}>
              <span>
                Details
              </span>
            </th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td className="consent-cell consent-cell--text">
              Your docs are available for
              download and print.<br/>
            </td>
          </tr>
          <br />
          <tr>
             <td>
                <table className={this.consentBox(pol)}>
                   <tbody>
                      <tr>
                         <td className="consent-cell consent-cell--text">
                            <label>
                                <input 
                                  type="radio"
                                  checked={this.consentGiven(pol)} 
                                  onChange={this.onAgreement(pol)} 
                                />
                               &nbsp;&nbsp; Agree and access
                            </label>
                         </td>
                      </tr>
                   </tbody>
                </table>
             </td>
          </tr>
          <tr>
             <td>
               <Button
                  onClick={this.showReissue}
                  primary={true}
                  fullWidth={false}
                  disabled={this.state.disableButton}
               >
                  If you cannot print in colour please click here
               </Button>
               <Reissue
                            handleClose={this.hideReissue} 
                            disableButton={this.disableButton}
                            showPrompt={this.state.showPrompt} 
                            pol={this.props.pol}
               />
             </td>
          </tr>
        </tbody>
      </table>
    );
  }
}

Leave a Comment