diff --git a/src/app/core/models/course.ts b/src/app/core/models/course.ts
index 6185a41dd86db35dc36c838348b7f3cf58d5c42a..a4e5c5c76f3350fc163f7b24cb2a63a97cf4b9e0 100644
--- a/src/app/core/models/course.ts
+++ b/src/app/core/models/course.ts
@@ -1,4 +1,4 @@
-interface CourseBase {
+export interface CourseBase {
   id: number | null;
   courseId: string;
   termCode: string | null;
@@ -31,3 +31,7 @@ interface CourseBase {
 export interface Course extends CourseBase {
   subject: string;
 }
+
+export interface SubjectMapping {
+  [subjectCode: number]: string;
+}
diff --git a/src/app/core/models/saved-for-later-course.ts b/src/app/core/models/saved-for-later-course.ts
index a9927d1d3567959f36f594818665b7456f8f66d4..aaee440dd9cc130d464d8d5414389d68426c9c32 100644
--- a/src/app/core/models/saved-for-later-course.ts
+++ b/src/app/core/models/saved-for-later-course.ts
@@ -1,4 +1,4 @@
-interface SavedForLaterCourseBase {
+export interface SavedForLaterCourseBase {
   id: number | null;
   courseId: string;
   termCode: string;
diff --git a/src/app/degree-planner/services/api.service.ts b/src/app/degree-planner/services/api.service.ts
index d1fbfde8fcde6b9112bdaaccb747e60981f4a076..34eb0048ad94895f99d17aca022ec0ae5844b956 100644
--- a/src/app/degree-planner/services/api.service.ts
+++ b/src/app/degree-planner/services/api.service.ts
@@ -12,9 +12,9 @@ import { ConfigService } from '@app/core/config.service';
 // Models
 import { Note } from '@app/core/models/note';
 import { Term } from '@app/core/models/term';
-import { Course } from '@app/core/models/course';
+import { Course, CourseBase, SubjectMapping } from '@app/core/models/course';
 import { DegreePlan } from '@app/core/models/degree-plan';
-import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
+import { SavedForLaterCourseBase } from '@app/core/models/saved-for-later-course';
 
 const HTTP_OPTIONS = {
   headers: new HttpHeaders({
@@ -26,8 +26,8 @@ const HTTP_OPTIONS = {
 export class DegreePlannerApiService {
   constructor(private http: HttpClient, private config: ConfigService) {}
 
-  public getSavedForLaterCourses(): Observable<SavedForLaterCourse[]> {
-    return this.http.get<SavedForLaterCourse[]>(
+  public getSavedForLaterCourses(): Observable<SavedForLaterCourseBase[]> {
+    return this.http.get<SavedForLaterCourseBase[]>(
       `${this.config.apiPlannerUrl}/favorites`,
     );
   }
@@ -40,8 +40,10 @@ export class DegreePlannerApiService {
     return this.http.get<DegreePlan>(this.degreePlanEndpoint(roadmapId));
   }
 
-  public getAllSubjects(): Observable<Object> {
-    return this.http.get<Object>(this.searchEndpoint('subjectsMap/0000'));
+  public getAllSubjects(): Observable<SubjectMapping> {
+    return this.http.get<SubjectMapping>(
+      this.searchEndpoint('subjectsMap/0000'),
+    );
   }
 
   public getActiveTerms(): Observable<Term[]> {
@@ -64,8 +66,8 @@ export class DegreePlannerApiService {
 
   public getAllTermCourses(
     roadmapId: number,
-  ): Observable<{ termCode: string; courses: Course[] }[]> {
-    return this.http.get<{ termCode: string; courses: Course[] }[]>(
+  ): Observable<{ termCode: string; courses: CourseBase[] }[]> {
+    return this.http.get<{ termCode: string; courses: CourseBase[] }[]>(
       this.degreePlanEndpoint(roadmapId, 'termcourses'),
     );
   }
@@ -110,8 +112,8 @@ export class DegreePlannerApiService {
   public saveForLater(
     subjectCode: string,
     courseId: string,
-  ): Observable<SavedForLaterCourse> {
-    return this.http.post<SavedForLaterCourse>(
+  ): Observable<SavedForLaterCourseBase> {
+    return this.http.post<SavedForLaterCourseBase>(
       this.config.apiPlannerUrl + '/favorites/' + subjectCode + '/' + courseId,
       HTTP_OPTIONS,
     );
@@ -120,8 +122,8 @@ export class DegreePlannerApiService {
   public removeSavedForLater(
     subjectCode: string,
     courseId: string,
-  ): Observable<SavedForLaterCourse> {
-    return this.http.delete<SavedForLaterCourse>(
+  ): Observable<SavedForLaterCourseBase> {
+    return this.http.delete<SavedForLaterCourseBase>(
       this.config.apiPlannerUrl + '/favorites/' + subjectCode + '/' + courseId,
       HTTP_OPTIONS,
     );
diff --git a/src/app/degree-planner/store/effects/plan.effects.ts b/src/app/degree-planner/store/effects/plan.effects.ts
index 094d1bb1d1e47d99aa3e87f6144cdcd0ec6da2b4..be19b723aab6f1a13bdc775496cb4ec4cb4adf46 100644
--- a/src/app/degree-planner/store/effects/plan.effects.ts
+++ b/src/app/degree-planner/store/effects/plan.effects.ts
@@ -26,6 +26,8 @@ import {
 // Models
 import { DegreePlan } from '@app/core/models/degree-plan';
 import { PlannedTerm } from '@app/core/models/planned-term';
+import { SubjectMapping } from '@app/core/models/course';
+import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
 
 @Injectable()
 export class DegreePlanEffects {
@@ -39,38 +41,56 @@ export class DegreePlanEffects {
   init$: Observable<InitialPlanLoadResponse> = this.actions$.pipe(
     ofType(ROOT_EFFECTS_INIT),
 
-    // Load all plans available to the user.
-    flatMap(() => this.api.getAllDegreePlans()),
+    // Load the data that is not specific to a particular degree plan. Also pick
+    // the primary degree plan as the first visible degree plan.
+    flatMap(() => {
+      return forkJoin(
+        this.api.getAllDegreePlans(),
+        this.api.getAllSubjects(),
+        this.api.getActiveTerms(),
+      ).pipe(
+        map(([allDegreePlans, subjects, activeTerms]) => {
+          const visibleDegreePlan =
+            allDegreePlans.find(plan => plan.primary) || allDegreePlans[0];
 
-    // Pick one of the plans to use as the visible plan.
-    map(allDegreePlans => {
-      return {
-        visibleDegreePlan:
-          allDegreePlans.find(plan => plan.primary) || allDegreePlans[0],
-        allDegreePlans,
-      };
+          return {
+            allDegreePlans,
+            subjects,
+            activeTermCodes: activeTerms.map(term => term.termCode),
+            visibleDegreePlan,
+          };
+        }),
+      );
     }),
 
     // Get term data for the degree plan specified by the roadmap ID and any
     // courses that were 'saved for later' by the user.
     flatMap(stdin => {
       return forkJoin(
-        this.loadTermsForPlan(stdin),
-        this.api.getSavedForLaterCourses(),
-        this.api.getAllSubjects(),
+        this.loadPlanTerms(
+          stdin.visibleDegreePlan,
+          stdin.subjects,
+          stdin.activeTermCodes,
+        ),
+        this.loadSavedForLaterCourses(stdin.subjects),
       ).pipe(
-        map(([planDetails, savedForLater, subjects]) => {
+        map(([visibleTerms, savedForLater]) => {
           const savedForLaterCourses = savedForLater.map(course => {
-            course.subject = subjects[course.subjectCode];
+            course.subject = stdin.subjects[course.subjectCode];
             return course;
           });
-          return { ...planDetails, savedForLaterCourses, subjects };
+
+          return new InitialPlanLoadResponse({
+            visibleDegreePlan: stdin.visibleDegreePlan,
+            visibleTerms,
+            savedForLaterCourses,
+            activeTermCodes: stdin.activeTermCodes,
+            allDegreePlans: stdin.allDegreePlans,
+            subjects: stdin.subjects,
+          });
         }),
       );
     }),
-
-    // Wrap data in an Action for dispatch
-    map(stdin => new InitialPlanLoadResponse(stdin)),
   );
 
   @Effect()
@@ -85,17 +105,37 @@ export class DegreePlanEffects {
     // corresponding degree plan object.
     map(([action, state]) => {
       return {
+        subjects: state.subjects,
         visibleDegreePlan: state.allDegreePlans.find(plan => {
           return plan.roadmapId === action.payload.newVisibleRoadmapId;
         }) as DegreePlan,
+        activeTermCodes: state.activeTermCodes,
       };
     }),
 
     // Get term data for the degree plan specified by the roadmap ID.
-    flatMap(stdin => this.loadTermsForPlan(stdin)),
+    flatMap(oldData => {
+      return this.loadPlanTerms(
+        oldData.visibleDegreePlan,
+        oldData.subjects,
+        oldData.activeTermCodes,
+      ).pipe(
+        map(visibleTerms => {
+          return {
+            visibleTerms,
+            visibleDegreePlan: oldData.visibleDegreePlan,
+          };
+        }),
+      );
+    }),
 
     // Wrap data in an Action for dispatch
-    map(stdin => new ChangeVisiblePlanResponse(stdin)),
+    map(data => {
+      return new ChangeVisiblePlanResponse({
+        visibleDegreePlan: data.visibleDegreePlan,
+        visibleTerms: data.visibleTerms,
+      });
+    }),
   );
 
   @Effect()
@@ -305,19 +345,32 @@ export class DegreePlanEffects {
     }),
   );
 
-  private loadTermsForPlan<T extends { visibleDegreePlan: DegreePlan }>(
-    stdin: T,
+  private loadSavedForLaterCourses(subjects: SubjectMapping) {
+    return this.api.getSavedForLaterCourses().pipe(
+      map(courseBases => {
+        return courseBases.map<SavedForLaterCourse>(base => {
+          return {
+            ...base,
+            subject: subjects[base.subjectCode] as string,
+          };
+        });
+      }),
+    );
+  }
+
+  private loadPlanTerms(
+    visibleDegreePlan: DegreePlan,
+    subjects: SubjectMapping,
+    activeTermCodes: string[],
   ) {
     return forkJoin(
-      this.api.getAllNotes(stdin.visibleDegreePlan.roadmapId),
-      this.api.getAllTermCourses(stdin.visibleDegreePlan.roadmapId),
-      this.api.getActiveTerms(),
+      this.api.getAllNotes(visibleDegreePlan.roadmapId),
+      this.api.getAllTermCourses(visibleDegreePlan.roadmapId),
     ).pipe(
       // Combine courses and notes by term.
-      map(([notes, termCourses, activeTerms]) => {
+      map(([notes, termCourses]) => {
         const noteTermCodes = notes.map(note => note.termCode);
         const courseTermCodes = termCourses.map(term => term.termCode);
-        const activeTermCodes = activeTerms.map(term => term.termCode);
 
         /**
          * Using the notes & courses relevant to the current degree plan and
@@ -335,11 +388,14 @@ export class DegreePlanEffects {
         const visibleTerms: PlannedTerm[] = uniqueTermCodes.map(termCode => {
           const note = notes.find(matchesTermCode(termCode));
           const termCourse = termCourses.find(matchesTermCode(termCode));
-          const courses = termCourse ? termCourse.courses : [];
+          const courses = (termCourse ? termCourse.courses : []).map(base => ({
+            ...base,
+            subject: subjects[base.subjectCode],
+          }));
           return { termCode, note, courses };
         });
 
-        return { ...stdin, visibleTerms, activeTermCodes };
+        return visibleTerms;
       }),
     );
   }
diff --git a/src/app/degree-planner/store/state.ts b/src/app/degree-planner/store/state.ts
index fc13fc4b0ec4809c99e3a822b25edb89904549ac..9cc6a2adaa8412d56aafaabcfe1d1e42b096c66d 100644
--- a/src/app/degree-planner/store/state.ts
+++ b/src/app/degree-planner/store/state.ts
@@ -2,6 +2,7 @@
 import { PlannedTerm } from '@app/core/models/planned-term';
 import { DegreePlan } from '@app/core/models/degree-plan';
 import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
+import { SubjectMapping } from '@app/core/models/course';
 
 export interface DegreePlannerState {
   visibleDegreePlan: DegreePlan | undefined;
@@ -9,7 +10,7 @@ export interface DegreePlannerState {
   savedForLaterCourses: SavedForLaterCourse[];
   activeTermCodes: string[];
   allDegreePlans: DegreePlan[];
-  subjects: Object;
+  subjects: SubjectMapping;
 }
 
 export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = {