# Objectives Redux This document outlines the current state of our Redux store in relation to objectives, outlines some of the issues with constistency across component store usage, and offers some suggestions for resolution. ## Current Redux State for Objectives Data Data for objectives are currently stored across several slices in the Redux store: ``` content: { courseObjectives: SMap<CourseObjective>; lessonObjectives: SMap<LessonObjective>; programOutlineTree: { pages: SMap<OutlinePage>; lessons: SMap<OutlineLesson>; courses: SMap<OutlineCourse>; } } ``` with corresponding (abreviated) types: #### Objective Data: ``` interface CourseObjective { ... parentCourseKey: string; associatedLessons: string[]; associatedProjects: string[]; lessonObjectiveKeys: string[]; } interface LessonObjective { ... parentCourseObjectiveKey: string; associatedPages: string[]; } ``` #### Outline Tree Data: ``` interface OutlineCourse { id: number; key: string; title: string; lessonKeys: string[]; ... objectiveKeys: string[]; updated_at: string; } interface OutlineLesson { id: number; key: string; title: string; ... pageKeys: string[]; objectiveKeys: string[]; isProjectLesson?: boolean; updated_at: string; } interface OutlinePage { id: number; key: string; title: string; notes?: string; objectiveKeys: string[]; parentLessonKey: string; updated_at: string; } ``` ``` content atoms _- loaded on-demand (when a user navigates to a parent page) since we do not need this data for outline view pages _- eager-load data necessary for outline view, the rest can be loaded on-demand when a user selects the page lessons courses nanodegree ``` ## Issues with Current State State usage seems to have changed since we started on objectives, and most of the selectors/reducers for objectives were written old assumptions about state. A `CourseObjective`'s `associatedLessons` are set when state is first read into Redux, but not updated in other components to keep in sync with the rest of the state. These are currently used in `objectiveGroups` for objective cards and so they need to be updated. A similar situation holds for `associatedProjects`. ## Suggestions - If they aren't used elsewhere, `associatedLessons` and `associatedProjects` can be removed from `CourseObjective`s along with the corresponding sections of the [objective program query](https://github.com/udacity/coco-web/blob/747345290e6123723e69bd09d0c03e2e4e09b518/src/app/features/program/state/queries.ts#L209) to load them. This will reduce any burden to maintain those parts of the state consistently. - The objective component can have selectors rewritten to compute corresponding projects and lessons as-needed. - Going forward, components will need to only mantain 1. `objectiveKeys` for Courses, Lessons, and Pages 2. `courseObjective` and `lessonObjective` data 3. `associatedPages`for lesson objectives. Note that we will still have the two-way relation between pages and lesson objectives: `LessonObjectives` have `associatedPages`, and pages have `objectiveKeys`. All other two-relations will be removed. ## New Store Shape ``` * `content` * `atoms` _- loaded on-demand (when a user navigates to a parent page) since we do not need this data for outline view * `pages` _- eager-load data necessary for outline view, the rest can be loaded on-demand when a user selects the page * `lessons` * `courses` * `nanodegree` * `courseObjective` // keep what we have today * `lessonObjective` // flat structure less complex selectors * `objective` // only benefit to nesting its prettier * `course` * `lesson` * `objectiveByCourse` * `objectiveByLesson` ```