Repository: freeCodeCamp/freeCodeCamp
File: client/src/redux/selectors.js (JavaScript)

Code before:

export const completedDailyCodingChallengesIdsSelector = createSelector(
  completedDailyCodingChallengesSelector,
  completedChallenges => completedChallenges.map(node => node.id)
);

export const completionStateSelector = createSelector(
  [
    allChallengesInfoSelector,
    completedChallengesIdsSelector,
    superBlockStructuresSelector,
    state => state.challenge.challengeMeta
  ],
  (
    allChallengesInfo,
    completedChallengesIds,
    superBlockStructures,
    challengeMeta
  ) => {
    if (!chapterBasedSuperBlocks.includes(challengeMeta.superBlock)) return [];

    const { challengeNodes } = allChallengesInfo;

    const structure = superBlockStructures[challengeMeta.superBlock];

    const chapters = structure.chapters;

    const getCompletionState = ({
      chapters,
      challenges,
      completedChallengesIds
    }) => {
      const populateBlocks = blocks =>
        blocks.map(block => {
          const blockChallenges = challenges.filter(
            ({ block: blockName }) => blockName === block
          );

          const completedBlockChallenges = blockChallenges.every(({ id }) =>
            completedChallengesIds.includes(id)
          );

          return {
            name: block,
            isCompleted:
              completedBlockChallenges.length === blockChallenges.length
          };
        });

      const populateModules = modules =>
        modules.map(module => {

Review comment (suggestion):
```suggestion
    const chapters = structure.chapters ?? [];
```
This might be a bit too cute, but this results in the selector returning `[]`

If it's not clear, we could just do `if (isEmpty(chapters)) return [];`

Code after:
export const completedDailyCodingChallengesIdsSelector = createSelector(
  completedDailyCodingChallengesSelector,
  completedChallenges => completedChallenges.map(node => node.id)
);

export const completionStateSelector = createSelector(
  [
    allChallengesInfoSelector,
    completedChallengesIdsSelector,
    superBlockStructuresSelector,
    state => state.challenge.challengeMeta
  ],
  (
    allChallengesInfo,
    completedChallengesIds,
    superBlockStructures,
    challengeMeta
  ) => {
    const { challengeNodes } = allChallengesInfo;

    const structure = superBlockStructures[challengeMeta.superBlock];

    const chapters = structure.chapters ?? [];

    const getCompletionState = ({
      chapters,
      challenges,
      completedChallengesIds
    }) => {
      const populateBlocks = blocks =>
        blocks.map(block => {
          const blockChallenges = challenges.filter(
            ({ block: blockName }) => blockName === block
          );

          const completedBlockChallenges = blockChallenges.every(({ id }) =>
            completedChallengesIds.includes(id)
          );

          return {
            name: block,
            isCompleted:
              completedBlockChallenges.length === blockChallenges.length
          };
        });

      const populateModules = modules =>
        modules.map(module => {
          const blocks = populateBlocks(module.blocks);
          const isCompleted = blocks.every(block => block.isCompleted === true);