diff --git a/src/app/degree-planner/actions/plan.actions.ts b/src/app/degree-planner/actions/plan.actions.ts
index 9d77b310a5cda8348720f24360f36784653370cd..be3559d9e5ab023295ef540f6a5661d6bbd1508b 100644
--- a/src/app/degree-planner/actions/plan.actions.ts
+++ b/src/app/degree-planner/actions/plan.actions.ts
@@ -5,7 +5,9 @@ import { DegreePlannerState } from '@app/degree-planner/state';
 export enum PlanActionTypes {
 	InitialPlanLoadResponse = '[Plan] Initial Load Response',
 	ChangeVisiblePlanRequest = '[Plan] Change Visible Request',
-	ChangeVisiblePlanResponse = '[Plan] Change Visible Response'
+	ChangeVisiblePlanResponse = '[Plan] Change Visible Response',
+	ChangeCourseTermRequest = '[Plan] Change Course Term Request',
+	ChangeCourseTermResponse = '[Plan] Change Course Term Response'
 }
 
 export class InitialPlanLoadResponse implements Action {
@@ -24,3 +26,17 @@ export class ChangeVisiblePlanResponse implements Action {
 		public payload: { visibleRoadmapId: number; visibleTerms: PlannedTerm[] }
 	) {}
 }
+
+export class ChangeCourseTermRequest implements Action {
+	public readonly type = PlanActionTypes.ChangeCourseTermRequest;
+	constructor(
+		public payload: {to: string, from: string, id: number}
+	) {}
+}
+
+export class ChangeCourseTermResponse implements Action {
+	public readonly type = PlanActionTypes.ChangeCourseTermResponse;
+	constructor(
+		public payload: {to: string, from: string, id: number}
+	) {}
+}
diff --git a/src/app/degree-planner/effects/plan.effects.ts b/src/app/degree-planner/effects/plan.effects.ts
index 4c5690ec70a4ab73091adae2156d3638300d56c8..d72480f39181964f1cc7cc92e03ab8d0e0c0d850 100644
--- a/src/app/degree-planner/effects/plan.effects.ts
+++ b/src/app/degree-planner/effects/plan.effects.ts
@@ -1,18 +1,22 @@
 // Libraries
 import { Injectable } from '@angular/core';
 import { ROOT_EFFECTS_INIT, Actions, Effect, ofType } from '@ngrx/effects';
-import { Observable, forkJoin, of } from 'rxjs';
-import { map, flatMap, tap } from 'rxjs/operators';
+import { Observable, forkJoin } from 'rxjs';
+import { map, flatMap, tap, withLatestFrom, filter } from 'rxjs/operators';
+import { GlobalState } from '@app/core/state';
+import { Store } from '@ngrx/store';
 
 // Services
 import { DegreePlannerApiService } from '@app/degree-planner/services/api.service';
+import { getDegreePlannerState } from '@app/degree-planner/selectors';
 
 // Actions
 import {
 	InitialPlanLoadResponse,
 	ChangeVisiblePlanRequest,
 	ChangeVisiblePlanResponse,
-	PlanActionTypes
+	PlanActionTypes,
+	ChangeCourseTermResponse
 } from '@app/degree-planner/actions/plan.actions';
 
 // Models
@@ -22,7 +26,8 @@ import { PlannedTerm } from '@app/core/models/planned-term';
 export class DegreePlanEffects {
 	constructor(
 		private actions$: Actions,
-		private api: DegreePlannerApiService
+		private api: DegreePlannerApiService,
+		private store$: Store<GlobalState>,
 	) {}
 
 	@Effect()
@@ -71,6 +76,41 @@ export class DegreePlanEffects {
 		map(stdin => new ChangeVisiblePlanResponse(stdin))
 	);
 
+	@Effect()
+	MoveCourseBetweenTerms$ = this.actions$.pipe(
+		ofType<any>(PlanActionTypes.ChangeCourseTermRequest),
+
+		withLatestFrom(this.store$.select(getDegreePlannerState)),
+		filter(([_, state]) => typeof state.visibleRoadmapId === 'number'),
+
+		// Get the roadmap ID from the action.
+		tap(([action, state]) => {
+			console.log(action);
+			console.log(state);
+		}),
+
+		// Get term data for the degree plan specified by the roadmap ID.
+		flatMap(([action, state]) => {
+			// TODO error handle the API calls
+			return this.api.updateCourseTerm(state.visibleRoadmapId, action.payload.id, action.payload.to).pipe(
+				map(response => {
+					return {
+						response,
+						action
+					};
+				})
+			);
+		}),
+
+		// // Wrap data in an Action for dispatch
+		map(({ response, action }) => {
+			if (response === 1) {
+				return new ChangeCourseTermResponse({ id: action.payload.id, from: action.payload.from, to: action.payload.to });
+			}
+			return;
+		})
+	);
+
 	private loadTermsForPlan<T extends { visibleRoadmapId: number }>(stdin: T) {
 		return forkJoin(
 			this.api.getAllNotes(stdin.visibleRoadmapId),
@@ -78,12 +118,12 @@ export class DegreePlanEffects {
 			this.api.getActiveTerms()
 		).pipe(
 			// Combine courses and notes by term.
-			map(([notes, courses, activeTerms]) => {
+			map(([notes, courses, currentTerms]) => {
 				/**
 				 * Using the notes & courses relevant to the current degree plan and
 				 * the active terms, generate a sorted list of all unqiue term codes.
 				 */
-				const uniqueTermCodes = [notes, courses, activeTerms]
+				const uniqueTermCodes = [notes, courses, currentTerms]
 					.map((ts: { termCode: string }[]) => ts.map(t => t.termCode))
 					.reduce((flat, nested) => flat.concat(nested), [])
 					.filter((termCode, index, self) => self.indexOf(termCode) === index)
@@ -101,7 +141,11 @@ export class DegreePlanEffects {
 					};
 				});
 
-				return Object.assign({}, stdin, { visibleTerms, activeTerms });
+				const activeTerms = uniqueTermCodes.filter(termCode => {
+					return parseInt(termCode, 10) >= parseInt(currentTerms[0].termCode, 10);
+				});
+
+				return Object.assign({}, stdin, { visibleTerms }, { activeTerms });
 			})
 		);
 	}
diff --git a/src/app/degree-planner/reducer.ts b/src/app/degree-planner/reducer.ts
index d25854cad006cd6a8db1d9c8350352441ba52edc..c2c277a917f7f890f8010f0ac5021b6367dfeb87 100644
--- a/src/app/degree-planner/reducer.ts
+++ b/src/app/degree-planner/reducer.ts
@@ -5,7 +5,9 @@ import {
 import {
 	PlanActionTypes,
 	InitialPlanLoadResponse,
-	ChangeVisiblePlanResponse
+	ChangeVisiblePlanResponse,
+	ChangeCourseTermRequest,
+	ChangeCourseTermResponse
 } from '@app/degree-planner/actions/plan.actions';
 import {
 	NoteActionTypes,
@@ -17,7 +19,8 @@ type SupportedActions =
 	| InitialPlanLoadResponse
 	| ChangeVisiblePlanResponse
 	| WriteNoteResponse
-	| DeleteNoteResponse;
+	| DeleteNoteResponse
+	| ChangeCourseTermResponse;
 
 export function degreePlannerReducer(
 	state = INITIAL_DEGREE_PLANNER_STATE,
@@ -112,6 +115,37 @@ export function degreePlannerReducer(
 			}
 		}
 
+		case PlanActionTypes.ChangeCourseTermResponse: {
+			const {to, from, id} = action.payload;
+			const t = state.visibleTerms.find(term => term.termCode === from);
+
+			if (t) {
+				const course = t.courses.find(c => c.id === id);
+
+				if (course) {
+					course.termCode = to;
+
+					// Create new visibleTerms array
+					const newVisibleTerms = state.visibleTerms.map(term => {
+						if (term.termCode === from) {
+							// Remove the course from the previous term
+							term.courses = term.courses.filter(c => c.id !== id);
+						} else if (term.termCode === to) {
+							// Add the new course to this term
+							term.courses = [...term.courses, course];
+						}
+						return term;
+
+					});
+
+					return {...state, visibleTerms: newVisibleTerms};
+				}
+
+				return state;
+			}
+			return state;
+		}
+
 		/**
 		 * It's okay if the action didn't match any of the cases above. If that's
 		 * the case, just return the existing state object.
diff --git a/src/app/degree-planner/selectors.ts b/src/app/degree-planner/selectors.ts
index 69738ae9754d18d9c7917ba26af6560b3b90fcc3..8ae9f2f19ed1385cd4424b85e165b66abe138878 100644
--- a/src/app/degree-planner/selectors.ts
+++ b/src/app/degree-planner/selectors.ts
@@ -62,6 +62,27 @@ export const getAllVisibleTermsByYear = createSelector(
 	}
 );
 
+export const getDropZones = createSelector(
+	getDegreePlannerState,
+	(state: DegreePlannerState) => {
+		return [
+			'saved-courses',
+			...state.activeTerms.map(termCode => {
+				return `term-${termCode}`;
+			})
+		];
+	}
+);
+
+export const isActiveTerm = (termCode: String) => createSelector(
+	getDegreePlannerState,
+	(state: DegreePlannerState) => {
+		console.log(termCode);
+		// return state.activeTerms.includes(termCode);
+		return true;
+	}
+);
+
 const getTermForCode = (termCode: string, courses: Course[], notes: Note[]) => {
 	return {
 		termCode,
diff --git a/src/app/degree-planner/services/api.service.ts b/src/app/degree-planner/services/api.service.ts
index 01cc151a8c9082f0c87ec5d5ba757dc7586e924e..287120260b70089447067bda044e86d053002377 100644
--- a/src/app/degree-planner/services/api.service.ts
+++ b/src/app/degree-planner/services/api.service.ts
@@ -53,6 +53,11 @@ export class DegreePlannerApiService {
 		);
 	}
 
+	public updateCourseTerm(roadmapId, recordId, termCode): Observable<any> {
+		return this.http.put<Course>(this.config.apiPlannerUrl + '/degreePlan/' +
+		roadmapId + '/courses/' + recordId + '?termCode=' + termCode, HTTP_OPTIONS);
+	}
+
 	public createNote(
 		planId: number,
 		termCode: string,
diff --git a/src/app/degree-planner/term-container/term-container.component.html b/src/app/degree-planner/term-container/term-container.component.html
index ac4765146f20c208176bd0f454d4008f6b9444fd..19ed83c3e3fc8a2d8342124f8910c044e630ecbc 100644
--- a/src/app/degree-planner/term-container/term-container.component.html
+++ b/src/app/degree-planner/term-container/term-container.component.html
@@ -27,7 +27,7 @@
 		<div cdkDropList
 			id="term-{{term.termCode}}"
 			[cdkDropListData]="term.courses"
-			[cdkDropListConnectedTo]="this.degreePlannerDataSvc.dropZones"
+			[cdkDropListConnectedTo]="dropZones$ | async"
 			class="course-list"
 			(cdkDropListDropped)="drop($event)">
 
@@ -43,6 +43,10 @@
 					<cse-course-item [course]="course"></cse-course-item>
 				</div>
 			</div>
+
+			<div class="no-courses" *ngIf="term.courses.length === 0">
+				<p>No Courses Taken</p>
+			</div>
 		</div>
 	</div>
 	<div class="add-new-wrapper">
diff --git a/src/app/degree-planner/term-container/term-container.component.scss b/src/app/degree-planner/term-container/term-container.component.scss
index 7e0c9e1a85f6c182754b9b78ac66c693e6facf22..618434dfc9e38606011038f6ea20c49b61747ee6 100644
--- a/src/app/degree-planner/term-container/term-container.component.scss
+++ b/src/app/degree-planner/term-container/term-container.component.scss
@@ -102,4 +102,10 @@
 		white-space: nowrap;
 		text-overflow: ellipsis;
 	}
+}
+
+.no-courses {
+	text-align: center;
+	padding: 25px 0;
+	font-weight: bold;
 }
\ No newline at end of file
diff --git a/src/app/degree-planner/term-container/term-container.component.ts b/src/app/degree-planner/term-container/term-container.component.ts
index 95d2beaab3d7963fb7dc8d2854ddefb9a895e3f4..1f4369255420c8c20a9550fdb3dfca554df50572 100644
--- a/src/app/degree-planner/term-container/term-container.component.ts
+++ b/src/app/degree-planner/term-container/term-container.component.ts
@@ -1,7 +1,23 @@
-import { Component, Input } from '@angular/core';
+// Libraries
+import { Component, Input, OnInit } from '@angular/core';
 import { CdkDragDrop } from '@angular/cdk/drag-drop';
 import { MatDialog } from '@angular/material';
 
+// rsjx / ngrx
+import { Observable } from 'rxjs';
+import { Store, select } from '@ngrx/store';
+import { DegreePlannerState } from '@app/degree-planner/state';
+import {
+	ChangeCourseTermRequest
+} from '@app/degree-planner/actions/plan.actions';
+
+// Selectors
+import {
+	getDropZones,
+	isActiveTerm
+} from '@app/degree-planner/selectors';
+
+// Services
 import { DataService } from '../../core/data.service';
 import { DegreePlannerDataService } from './../../core/service/degree-planner-data.service';
 import { SidenavService } from './../../core/service/sidenav.service';
@@ -18,16 +34,26 @@ import {
 	templateUrl: './term-container.component.html',
 	styleUrls: ['./term-container.component.scss']
 })
-export class TermContainerComponent {
+export class TermContainerComponent implements OnInit {
 	@Input() term: PlannedTerm;
+	public dropZones$: Observable<String[]>;
+	public isActiveTerm$: Observable<Boolean>;
 
 	constructor(
 		private dataService: DataService,
 		public degreePlannerDataSvc: DegreePlannerDataService,
 		public dialog: MatDialog,
-		private sidenavService: SidenavService
+		private sidenavService: SidenavService,
+		private store: Store<{ degreePlanner: DegreePlannerState }>,
 	) {}
 
+	public ngOnInit() {
+		this.dropZones$ = this.store.pipe(select(getDropZones));
+		this.isActiveTerm$ = this.store.pipe(select(isActiveTerm(this.term.termCode)));
+	}
+
+	// this.dropZones$ = this.store.pipe(select(getDropZones));
+
 	public openAddSidenav(): void {
 		this.sidenavService.open();
 	}
@@ -47,54 +73,64 @@ export class TermContainerComponent {
 	}
 
 	drop(event: CdkDragDrop<string[]>) {
-		const { container, previousContainer, previousIndex } = event;
-
-		// Get the course JSON
-		const item = event.item.data;
-
-		console.log(event);
-
-		const newTermCode = event.container.id.substr(5, 4);
-
-		if (
-			event.previousContainer.id === 'saved-courses' &&
-			event.container.id !== 'saved-courses'
-		) {
-			// If moving from favorites to term
-			container.data.push(item);
-			previousContainer.data.splice(previousIndex, 1);
-
-			this.dataService
-				.addCourse(
-					this.degreePlannerDataSvc.getPlanId(),
-					event.item.data.subjectCode,
-					event.item.data.courseId,
-					newTermCode
-				)
-				.subscribe(data => {
-					const yearCode = newTermCode.substring(0, 3);
-					const termCode = newTermCode.substring(3);
-				});
-
-			this.dataService
-				.removeFavoriteCourse(
-					event.item.data.subjectCode,
-					event.item.data.courseId
-				)
-				.subscribe();
-		} else if (event.previousContainer.id !== event.container.id) {
-			container.data.push(item);
-			previousContainer.data.splice(previousIndex, 1);
-
-			// Tell the API this course updated
-			this.dataService
-				.updateCourseTerm(
-					this.degreePlannerDataSvc.getPlanId(),
-					event.item.data.id,
-					newTermCode
-				)
-				.subscribe();
+		const to = event.container.id.substr(5);
+		const { termCode: from, id } = event.item.data;
+
+		if (from === to) {
+			return;
 		}
+
+		console.log(to);
+		console.log(from);
+		console.log(id);
+		this.store.dispatch(new ChangeCourseTermRequest({ to, from, id }));
+
+		// // Get the course JSON
+		// const item = event.item.data;
+
+		// console.log(event);
+
+		// const newTermCode = event.container.id.substr(5, 4);
+
+		// if (
+		// 	event.previousContainer.id === 'saved-courses' &&
+		// 	event.container.id !== 'saved-courses'
+		// ) {
+		// 	// If moving from favorites to term
+		// 	container.data.push(item);
+		// 	previousContainer.data.splice(previousIndex, 1);
+
+		// 	this.dataService
+		// 		.addCourse(
+		// 			this.degreePlannerDataSvc.getPlanId(),
+		// 			event.item.data.subjectCode,
+		// 			event.item.data.courseId,
+		// 			newTermCode
+		// 		)
+		// 		.subscribe(data => {
+		// 			const yearCode = newTermCode.substring(0, 3);
+		// 			const termCode = newTermCode.substring(3);
+		// 		});
+
+		// 	this.dataService
+		// 		.removeFavoriteCourse(
+		// 			event.item.data.subjectCode,
+		// 			event.item.data.courseId
+		// 		)
+		// 		.subscribe();
+		// } else if (event.previousContainer.id !== event.container.id) {
+		// 	container.data.push(item);
+		// 	previousContainer.data.splice(previousIndex, 1);
+
+		// 	// Tell the API this course updated
+		// 	this.dataService
+		// 		.updateCourseTerm(
+		// 			this.degreePlannerDataSvc.getPlanId(),
+		// 			event.item.data.id,
+		// 			newTermCode
+		// 		)
+		// 		.subscribe();
+		// }
 		// Do nothing on drop to same term
 	}
 }