Importing function and getting props with "this": "TypeError: Cannot read property 'renderElapsedString' of undefined"

Viewed 3296

I'm new to React and I'm creating a time logging app from the FullStackReact book, but using the ES6 'extends' module instead of Create Class. With that said, I'm getting this error and I'm out of ideas as to what's going on.

TypeError: Cannot read property 'renderElapsedString' of undefined

EDIT: After removing the curly bracers from my 'helpers' import, I'm receiving a new error

TypeError: __WEBPACK_IMPORTED_MODULE_2__helpers___default.a.renderElapsedString is not a function

Final Edit: The problem was my helpers.js file, I wasn't exporting the functions, which is why the function itself was undefined.

    import React from 'react';
    import EditableTimerList from './EditableTimerList';
    import helpers from '../helpers';

    class Timer extends React.Component {
      render() {
          const elapsedString = helpers.renderElapsedString(this.props.elapsed)
        return(
          <div className="ui centered card">
            <div className="content">
              <div className="header">
                {this.props.title}
              </div>
              <div className="meta">{this.props.projects}
              </div>
              <div className="center aligned description">
                <h2>{elapsedString}</h2>
              </div>
              <div className="extra content">
                <span className="right floated edit icon">
                  <i className="edit icon"></i>
                </span>
                <span className="right floated trash icon">
                  <i className="trash icon"></i>
                </span>
              </div>
            </div>
            <div className="ui bottom attached blue basic button">Start</div>
          </div>
        )
      }
    }

    export default Timer;

and here's my EditableTimer code

import React from 'react';
import helpers from '../helpers'
import EditableTimer from './EditableTimer'

class EditableTimerList extends React.Component {
  render() {
    return (
      <div id="timers">
        <EditableTimer
          title="Learn React"
          project="Web Domination"
          elapsed='8986300'
          runningSince={null}
          editFormOpen={false}
        />
        <EditableTimer
          title="Learn Extreme Ironing"
          project="Web Domination"
          elapsed='3890985'
          runningSince={null}
          editFormOpen={true}
        />
      </div>
    )
  }
}

export default EditableTimerList;

And here's my helpers file:

    export function newTimer(attrs = {}) {
    return {
        title: attrs.title || 'Timer',
        project: attrs.project || 'Project',
        id: uuid.v4(), // eslint-disable-line no-undef
        elapsed: 0
    };
}

export function findById(array, id, cb) {
    cb(array.find(el => el.id === id));
}

export function renderElapsedString(elapsed, runningSince) {
    let totalElapsed = elapsed;
    if (runningSince) {
        totalElapsed += Date.now() - runningSince;
    }
    return millisecondsToHuman(totalElapsed);
}

export function millisecondsToHuman(ms) {
    const seconds = Math.floor((ms / 1000) % 60);
    const minutes = Math.floor((ms / 1000 / 60) % 60);
    const hours = Math.floor(ms / 1000 / 60 / 60);

    return [
        pad(hours.toString(), 2),
        pad(minutes.toString(), 2),
        pad(seconds.toString(), 2)
    ].join(':');

}

export function pad(numberString, size) {
    let padded = numberString;
    while (padded.length < size) padded = '0' + padded;
    return padded;
}

export default {
    millisecondsToHuman: millisecondsToHuman,
    newTimer: newTimer,
    findById: findById,
    renderElapsedString: renderElapsedString
};
1 Answers
Related