Skip to content

Learner App - Sidebar unitid undefined TypeError #1747

@wgu-jesse-stewart

Description

@wgu-jesse-stewart

Description

The learner app throws a TypeError when viewing locked units due to activeUnitId being null, causing undefined property access errors in the sidebar component. This occurs when learners attempt to interact with units they don't have access to.

Environment

  • Platform: OpenEdX
  • Component: Learner App - Sidebar
  • Tutor Version: Teak

Error Details

TypeError: Cannot read properties of undefined (reading 'unitIds')

Call Stack:
logEvent
  src/courseware/course/sidebar/sidebars/course-outline/hooks.js:100:37
handleUnitClick
  src/courseware/course/sidebar/sidebars/course-outline/hooks.js:112:5
onClick
  src/courseware/course/sidebar/sidebars/course-outline/components/UnitLinkWrapper.tsx:49:20
handleClick
  node_modules/react-router-dom/dist/index.js:560:18
HTMLUnknownElement.callCallback
  node_modules/react-dom/cjs/react-dom.development.js:4164:14
Object.invokeGuardedCallbackDev
  node_modules/react-dom/cjs/react-dom.development.js:4213:16
invokeGuardedCallback
  node_modules/react-dom/cjs/react-dom.development.js:4277:31
invokeGuardedCallbackAndCatchFirstError
  node_modules/react-dom/cjs/react-dom.development.js:4291:25
executeDispatch
  node_modules/react-dom/cjs/react-dom.development.js:9041:3
processDispatchQueueItemsInOrder
  node_modules/react-dom/cjs/react-dom.development.js:9073:7
processDispatchQueue
  node_modules/react-dom/cjs/react-dom.development.js:9086:5

Root Cause

When a learner navigates to a locked unit, activeUnitId becomes null. Subsequently, when clicking on any other unit, the following functions still attempt to execute with a null activeUnitId:

  • sendTrackEvent
  • sendTrackingLogEvent
  • checkBlockCompletion

These functions expect a valid unitId but receive undefined/null, causing the TypeError when trying to access properties of the undefined value.

Steps to Reproduce

  1. Set up a course with unit prerequisites (locked units)
  2. Log in as a learner who hasn't completed the prerequisite
  3. Navigate to the course outline sidebar
  4. Navigate to a locked unit
  5. Attempt to click on another unit (any unit)
  6. Observe the TypeError in browser console
  7. Notice that tracking events and completion checks fail

Expected Behavior

  • After viewing a locked unit, clicking on other units should work normally
  • The app should gracefully handle null/undefined activeUnitId states
  • Sidebar navigation should remain functional even after interacting with locked content
  • Tracking events should either be skipped or handled with default values when activeUnitId is null

Actual Behavior

  • After viewing a locked unit, activeUnitId becomes null
  • Subsequent clicks on any unit throw TypeError when accessing properties of undefined
  • JavaScript execution halts, breaking sidebar navigation functionality
  • All tracking and completion checking fails until page refresh

Proposed Solution

Add defensive programming to the affected functions:

In handleUnitClick function:

javascript

const handleUnitClick = (unitId) => {
  if (!unitId || !activeUnitId) {
    // Handle locked unit case gracefully
    return;
  }
  // Existing logic...
};

In checkBlockCompletion function:

javascript

const checkBlockCompletion = () => {
  if (!activeUnitId) {
    // Skip completion check for locked/undefined units
    return;
  }
  // Existing logic...
};

Alternative Approach:

If tracking events need to run even for locked units, modify the functions to handle the locked state:

javascript

const sendTrackEvent = (unitId = null) => {
  const trackingData = {
    unitId: unitId || 'locked_unit',
    // ... other properties
  };
  // Send tracking event with appropriate defaults
};

Impact

  • Severity: Medium-High - Breaks sidebar navigation after viewing locked content
  • Affected Users: Learners accessing courses with prerequisites
  • Frequency: Occurs every time a learner navigates to a locked unit and then tries to access other units

Metadata

Metadata

Labels

bugReport of or fix for something that isn't working as intended

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions