Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: TypeError: Cannot convert undefined or null to object

I am running a React application.

When I enter the page through routes(click button or link) page works fine but when I reload the page it crashes. I cannot see where the error is, the console and source show just blank, this is the server message console message.

server: Entrypoint index [big] = index.js index.1af9d975ff74be4d27d9.hot-update.js index.c93bf08301ec20c0dc85.js.map index.c93bf08301ec20c0dc85.js.map
server:    533 modules
server: backend debug read session { csrfToken: '0ae87c36d850008df20b58941bf89072', id: 2 }
server: backend debug {"data":{"currentUser":null}} <= undefined
server: backend debug {"data":{"currentUser":null}} <= undefined
server: backend debug read session {}
server: backend error TypeError: Cannot convert undefined or null to object
server:     at getPrototypeOf (<anonymous>)
server:     at hoistNonReactStatics (/Users/apple/Desktop/dev/bethabit/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js:71:38)
server:     at resolveComponent (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:332:3)
server:     at InnerLoadable.loadSync (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:189:24)
server:     at new InnerLoadable (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:138:17)
server:     at processChild (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3048:14)
server:     at resolve (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3013:5)
server:     at ReactDOMServerRenderer.render (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3436:22)
server:     at ReactDOMServerRenderer.read (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3395:29)
server:     at renderToStaticMarkup (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3969:27)
server:     at process (/Users/apple/Desktop/dev/bethabit/node_modules/@apollo/react-ssr/lib/react-ssr.cjs.js:38:16)
server:     at process._tickCallback (internal/process/next_tick.js:68:7)
server: backend debug read session { id: 3 }
server: backend debug loading <= currentUser
server: backend debug loading <= currentUser
server: backend debug loading <= currentUser
server: backend debug {"data":{"currentUser":{"id":3,"username":"[email protected]","role":"user","isActive":true,"email":"[email protected]","__typename":"User"}}} <= currentUser
server: backend debug {"data":{"currentUser":{"id":3,"username":"[email protected]","role":"user","isActive":true,"email":"[email protected]","__typename":"User"}}} <= currentUser
server: backend debug {"data":{"currentUser":{"id":3,"username":"[email protected]","role":"user","isActive":true,"email":"[email protected]","profile":{"firstName":"Caner","lastName":"Çakmak","fullName":"Caner Çakmak","__typename":"UserProfile"},"auth":{"certificate":null,"facebook":{"fbId":null,"displayName":null,"__typename":"FacebookAuth"},"google":{"googleId":"104801577244556473676","displayName":"Caner Çakmak","__typename":"GoogleAuth"},"github":null,"linkedin":null,"__typename":"UserAuth"},"__typename":"User"}}} <= currentUser
server: backend debug read session {}
server: backend error TypeError: Cannot convert undefined or null to object
server:     at getPrototypeOf (<anonymous>)
server:     at hoistNonReactStatics (/Users/apple/Desktop/dev/bethabit/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js:71:38)
server:     at resolveComponent (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:332:3)
server:     at InnerLoadable.loadSync (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:189:24)
server:     at new InnerLoadable (/Users/apple/Desktop/dev/bethabit/node_modules/@loadable/component/dist/loadable.cjs.js:138:17)
server:     at processChild (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3048:14)
server:     at resolve (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3013:5)
server:     at ReactDOMServerRenderer.render (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3436:22)
server:     at ReactDOMServerRenderer.read (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3395:29)
server:     at renderToStaticMarkup (/Users/apple/Desktop/dev/bethabit/node_modules/react-dom/cjs/react-dom-server.node.development.js:3969:27)
server:     at process (/Users/apple/Desktop/dev/bethabit/node_modules/@apollo/react-ssr/lib/react-ssr.cjs.js:38:16)
server:     at process._tickCallback (internal/process/next_tick.js:68:7)

this is the code that runs. I tried removing currentuser, addhabit and many other things to just to understand where the error comes from. No results. Everything works fine if I enter the page through a link.

HabitaddView.web.jsx

const HabitAddView = ({ addHabit, t, currentUser }) => {
  const renderMetaData = () => (
    <Helmet
      title={`${settings.app.name} - ${t('habit.title')}`}
      meta={[
        {
          name: 'description',
          content: t('habit.meta')
        }
      ]}
    />
  );
  return (
    <PageLayout>
      {renderMetaData()}
      <div className="row">
        <div className="col-sm-12 padTop10">
          <h2>{t(`habit.label.create_new`)}</h2>
        </div>
      </div>
      <HabitForm onSubmit={onSubmit(addHabit)} currentUser={currentUser} />
    </PageLayout>
  );
};

HabitForm.web.jsx

const HabitForm = ({ values, handleSubmit, setFieldValue, submitting, t  }) => {
  const [habitType, sethabitType] = useState('Fitness Habits');
  const [intervalText, setIntervalText] = useState(t('habit.field.interval'));

  const [habitActions, sethabitActions] = useState([]);
  const [habitFreqs, sethabitFreqs] = useState([]);
  const [habitDurations, sethabitDurations] = useState([]);
  const [habitIntervals, sethabitIntervals] = useState([]);

  const [showInterval, setshowInterval] = useState(true);
  const [showHabitDiv, setshowHabitDiv] = useState(false);

  const [habitActionDisabled, sethabitActionDisabled] = useState(true);
  let calendarComponentRef = React.createRef();
  let calendarWeekends = true;
  let [calendarEvents, setCalendarEvents] = useState([]);

  var timeZones = moment.tz.names();

  const handleHabitTypeChange = (type, value, setFieldValue) => {
    setFieldValue(type, value);
    resetValues();
    Object.values(settings.habits.list).map(object => {
      if (object.habit_type == value) {
        const _habitActions = [];
        Object.values(object.habit_actions).map(object2 => {
          _habitActions.push(object2.title);
        });
        sethabitType(value);
        sethabitActions(_habitActions);
        setshowHabitDiv(false);
        sethabitActionDisabled(false);
      }
    });
  };

  const updateIntervalText = worktype => {
    if (worktype === 5) {
      setIntervalText(t('habit.field.number'));
    } else if (worktype === 6 || worktype === 7) {
      setIntervalText(t('habit.field.proof'));
    } else {
      setIntervalText(t('habit.field.interval'));
    }
  };

  const handleHabitActionChange = (type, value, setFieldValue) => {
    const preparedValue = Array.isArray(value) ? value[0] : value;
    setFieldValue(type, preparedValue);
    const _habitFreqs = [];
    const _habitDurations = [];
    const _habitIntervals = [];
    resetValues();
    Object.values(settings.habits.list).map(object => {
      if (object.habit_type == habitType) {
        Object.values(object.habit_actions).map(object2 => {
          if (object2.title == preparedValue) {
            Object.values(object2.duration).map(object4 => {
              _habitDurations.push(object4);
            });
            Object.values(object2.interval).map(object5 => {
              _habitIntervals.push(object5);
            });
            sethabitFreqs(_habitFreqs);
            sethabitIntervals(_habitIntervals);
            sethabitDurations(_habitDurations);
            setshowHabitDiv(true);
            setFieldValue('timezone', moment.tz.guess());
            setFieldValue('worktype', object2.worktype);
            setFieldValue('description', object2.description);
            setFieldValue('misc', JSON.stringify(object2.misc));
            updateIntervalText(object2.worktype);
          }
        });
      }
    });
  };

  const handleValueChange = (type, value, setFieldValue) => {
    const preparedValue = value;
    setFieldValue(type, preparedValue);
    let timezone = values.timezone;
    let interval = values.interval;
    let duration = values.duration;
    if (type === 'timezone') {
      timezone = value;
    } else if (type === 'interval') {
      interval = value;
    } else if (type === 'duration') {
      duration = value;
    }
    updateCalendarEvents(values.habit_action, timezone, interval, duration);
  };

  const empty = e => {
    switch (e) {
      case '':
      case 0:
      case '0':
      case null:
      case false:
      case typeof this == 'undefined':
        return true;
      default:
        return false;
    }
  };

  const resetValues = () => {
    values.duration = '';
    values.interval = '';
    values.timezone = '';
    updateCalendarEvents(values.habit_action, values.timezone, values.interval, values.duration);
  };

  const updateCalendarEvents = (habit_action, timezone, interval, duration) => {
    setCalendarEvents([]);
    let events = [];
    if (!empty(timezone) && !empty(interval) && !empty(duration)) {
      var dur = JSON.parse(duration);
      var int = JSON.parse(interval);
      var times = dur.count;
      var counter = 0;
      for (var i = 0; i < times; i++) {
        if (i % int.step === 0) {
          counter += 1;
          var obj = {
            title: values.habit_action + ' ' + int.title,
            start: moment
              .tz(values.timezone)
              .add(i + 1, 'days')
              .format(),
            allDay: true
          };
          let addObj = true;
          if (values.worktype === 7 && i === 0) {
            addObj = false;
          }
          if (dur.weekdays === true && (moment(obj.start).isoWeekday() === 6 || moment(obj.start).isoWeekday() === 7)) {
            addObj = false;
          }
          if (
            values.worktype === 7 &&
            counter > 2 &&
            counter < 10 &&
            (habit_action === 'Stay Alcohol Free' || (habit_action === 'Stay Nicotine Free' && dur.count === 28))
          ) {
            obj.start = moment
              .tz(values.timezone)
              .add(i + (counter - 1), 'days')
              .format();
            true;
          }
          if (addObj) {
            events.push(obj);
          }
        }
      }
      if (habit_action === 'Stay Alcohol Free' && dur.count === 28) {
        events.sort(function(a, b) {
          return moment(b.start) - moment(a.start);
        });
        events.shift();
        events.shift();
      }
      setCalendarEvents(events);
    }
  };
  if (settings.habits.list) {
    return (
      <div className="row">
        <div className="col-sm-5">
          <div className="card">
            <div className="card-body">
              <Form name="habit" onSubmit={handleSubmit}>
                <Field
                  name="habit_type"
                  component={RenderSelect}
                  type="select"
                  label={t('habit.field.habit_type')}
                  value={values.habit_type}
                  onChange={value => handleHabitTypeChange('habit_type', value, setFieldValue)}
                  cols={1}
                >
                  <Option value={0}>--Please Select--</Option>
                  {Object.values(settings.habits.list).map((object, i) => {
                    return (
                      <Option key={i} value={object.habit_type}>
                        {object.habit_type}
                      </Option>
                    );
                  })}
                </Field>

habitadd.jsx

class HabitAdd extends React.Component {
  static propTypes = {
    currentUser: PropTypes.object
  };

  constructor(props) {
    super(props);
    this.subscription = null;
    this.state = { options: [] };
  }

  render() {
    if ( this.props.currentUser) {
      return <HabitAddView {...this.props} />;
    } else {
      return <div></div>;
    }
  }
}

export default compose(
  graphql(ADD_HABIT, {
    props: ({ ownProps: { history, navigation }, mutate }) => ({
      addHabit: async (
        habit_type,
        habit_action,
        duration,
        interval,
        timezone,
        description,
        worktype,
        misc,
        user_id
      ) => {
        let habitData = await mutate({
          variables: {
            input: {
              habit_type: habit_type,
              habit_action: habit_action,
              duration: duration,
              interval: interval,
              timezone: timezone,
              description: description,
              worktype: worktype,
              misc: misc,
              user_id: user_id
            }
          },
          optimisticResponse: {
            __typename: 'Mutation',
            addHabit: {
              __typename: 'Habit',
              id: null,
              habit_type: habit_type,
              habit_action: habit_action,
              duration: duration,
              interval: interval,
              timezone: timezone,
              description: description,
              worktype: worktype,
              misc: misc,
              user_id: user_id,
              days: [],
              bets: []
            }
          }
        });

        if (history) {
          window.location.href = window.location.origin + '/habit/' + habitData.data.addHabit.id;
        } else if (navigation) {
          return navigation.push('HabitEdit', { id: habitData.data.addHabit.id });
        }
      }
    })
  }),
  graphql(CURRENT_USER_QUERY, {
    props({ data: { error, currentUser } }) {
      if (error) throw new Error(error);
      return { currentUser };
    }
  })
)(HabitAdd);

Thanks to Ace, I realized my mistake. Added this code line on habitAdd render method

render() {
    if ( this.props.currentUser) {
      return <HabitAddView {...this.props} />;
    } else {
      return <div></div>;
    }
  }
like image 805
Caner Avatar asked Nov 26 '19 08:11

Caner


1 Answers

The issue is with the currentUser. Consider initializing it. Before routing I am assuming you are setting the value for the currentUser or the currentUser is being set to a value, but on refresh, the value is reset, though the component will load, the value for currentUser isn't available hence the error.

like image 101
Ace Avatar answered Oct 05 '22 23:10

Ace