Skip to content

Instantly share code, notes, and snippets.

@jhades
Last active July 20, 2018 10:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhades/70d930f693d6b46ece49d865c1c60ad6 to your computer and use it in GitHub Desktop.
Save jhades/70d930f693d6b46ece49d865c1c60ad6 to your computer and use it in GitHub Desktop.
export interface Course {
id:number;
description:string;
iconUrl?: string;
courseListIcon?: string;
longDescription?: string;
category:string;
seqNo: number;
lessonsCount?:number;
promo?:boolean;
}
export interface Lesson {
id: number;
description: string;
duration: string;
seqNo: number;
courseId?: number;
videoId?: string;
}
{
courses: [
{
id: 0,
description: "Angular Ngrx Course",
category: 'BEGINNER',
seqNo: 1
},
{
id: 1,
description: "Angular for Beginners",
category: 'BEGINNER',
seqNo: 2
},
{
id: 2,
description: 'Angular Security Course - Web Security Fundamentals',
category: 'ADVANCED',
seqNo: 3
},
...
],
lessons: [
{
id: 1,
"description": "Angular Tutorial For Beginners - Build Your First App - Hello World Step By Step",
"duration": "4:17",
"seqNo": 1,
courseId: 1
},
{
id: 2,
"description": "Building Your First Component - Component Composition",
"duration": "2:07",
"seqNo": 2,
courseId: 1
},
...
]
}
{
courses: {
0: {
id: 0,
description: "Angular Ngrx Course",
category: 'BEGINNER',
seqNo: 1
},
},
1: {
id: 1,
description: "Angular for Beginners",
category: 'BEGINNER',
seqNo: 2
},
2: {
id: 2,
description: "Angular Security Course - Web Security Fundamentals",
category: 'BEGINNER',
seqNo: 3
}
},
lessons: {
1: {
id: 1,
"description": "Angular Tutorial For Beginners - Build Your First App - Hello World Step By Step",
"duration": "4:17",
"seqNo": 1,
courseId: 1
},
2: {
id: 2,
"description": "Building Your First Component - Component Composition",
"duration": "2:07",
"seqNo": 2,
courseId: 1
},
....
35: {
id: 35,
"description": "Unidirectional Data Flow And The Angular Development Mode",
"duration": "7:07",
"seqNo": 6,
courseId: 0
}
}
}
{
courses: {
ids: [0, 1, 2],
entities: {
0: {
id: 0,
description: "Angular Ngrx Course",
category: 'BEGINNER',
seqNo: 1
},
},
1: {
id: 1,
description: "Angular for Beginners",
category: 'BEGINNER',
seqNo: 2
},
2: {
id: 2,
description: "Angular Security Course - Web Security Fundamentals",
category: 'BEGINNER',
seqNo: 3
}
}
},
lessons: {
ids: [1, 2, ... 35],
entities: {
1: {
id: 1,
"description": "Angular Tutorial For Beginners - Build Your First App - Hello World Step By Step",
"duration": "4:17",
"seqNo": 1,
courseId: 1
},
2: {
id: 2,
"description": "Building Your First Component - Component Composition",
"duration": "2:07",
"seqNo": 2,
courseId: 1
},
....
35: {
id: 35,
"description": "Unidirectional Data Flow And The Angular Development Mode",
"duration": "7:07",
"seqNo": 6,
courseId: 0
}
}
}
}
export interface StoreState {
courses: CourseState:
lessons: LessonsState;
}
export interface CoursesState {
ids: number[];
entities: {[key:number]: Course};
}
export interface LessonsState {
ids: number[];
entities: {[key:number]: Lesson};
}
const initialCoursesState: CoursesState = {
ids: [],
entities: {}
}
function sortBySeqNo(e1: Course, e2: Course) {
return e1.seqNo - e2.seqNo;
}
export function coursesReducer(
state = initialCoursesState,
action: CourseActions): CoursesState {
switch (action.type) {
case CourseActionTypes.COURSE_LOADED:
// push new id to array and re-order
const ids = state.ids.slice(0);
ids.push(action.course.id);
ids.sort(sortBySeqNo);
// build a new courses state
return {
ids,
entities: {
...state.entities,
action.payload.course
}
};
default:
return state;
}
}
const initialLessonsState: LessonsState = {
ids: [],
entities: {}
}
function sortBySeqNo(e1: Lesson, e2: Lesson) {
return e1.seqNo - e2.seqNo;
}
export function lessonsReducer(
state = initialLessonsState,
action: LessonActions): LessonsState {
switch (action.type) {
case CourseActionTypes.LESSON_LOADED:
// push new id to array and re-order
const ids = state.ids.slice(0);
ids.push(action.lesson.id);
ids.sort(sortBySeqNo);
return {
ids,
entities: {
...state.entities,
action.payload.lesson
}
};
default:
return state;
}
}
export const selectCoursesState =
createFeatureSelector<CoursesState>("courses");
export const selectAllCourses = createSelector(
selectCoursesState,
coursesState => {
const allCourses = Object.values(coursesState.entities)
allCourses.sort(sortBySeqNo);
return allCourses;
}
);
export const selectLessonsState =
createFeatureSelector<LessonsState>("lessons");
export const selectAllLessons = createSelector(
selectLessonsState,
lessonsState => {
const allLessons = Object.values(lessonsState.entities)
allLessons.sort(sortBySeqNo);
return allLessons;
}
);
export interface CoursesState extends EntityState<Course> {
}
export const adapter : EntityAdapter<Course> =
createEntityAdapter<Course>({
sortComparer: sortBySeqNo
});
export interface CoursesState extends EntityState<Course> {
allCoursesLoaded:boolean;
}
export const initialCoursesState: CoursesState =
adapter.getInitialState();
export function lessonsReducer(
state = initialLessonsState,
action: LessonActions): LessonsState {
switch (action.type) {
case CourseActionTypes.LESSON_LOADED:
return adapter.addOne(action.payload.course, state);
default:
return state;
}
}
export function coursesReducer(
state = initialCoursesState,
action: CourseActions): CoursesState {
switch (action.type) {
case CourseActions.ADD_COURSE: {
return adapter.addOne(action.payload.course, state);
}
case CourseActions.UPSERT_COURSE: {
return adapter.upsertOne(action.payload.course, state);
}
case CourseActions.ADD_COURSES: {
return adapter.addMany(action.payload.courses, state);
}
case CourseActions.UPSERT_COURSES: {
return adapter.upsertMany(action.payload.courses, state);
}
case CourseActions.UPDATE_COURSE: {
return adapter.updateOne(action.payload.course, state);
}
case CourseActions.UPDATE_COURSES: {
return adapter.updateMany(action.payload.courses, state);
}
case CourseActions.DELETE_COURSE: {
return adapter.removeOne(action.payload.id, state);
}
case CourseActions.DELETE_COURSES: {
return adapter.removeMany(action.payload.ids, state);
}
case CourseActions.LOAD_COURSES: {
return adapter.addAll(action.payload.courses, state);
}
case CourseActions.CLEAR_COURSES: {
return adapter.removeAll(state);
}
default: {
return state;
}
}
}
export const {
selectAll,
selectEntities,
selectIds,
selectTotal
} = adapter.getSelectors();
import * as fromCourses from './courses.reducers';
// this is equivalent to selectAllCourses
// that we wrote manually before
const selectAllCourses = fromCourses.selectAll;
export interface LessonsState extends EntityState<Lesson> {
}
export const adapter : EntityAdapter<Lesson> =
createEntityAdapter<Lesson>({sortComparer: sortBySeqNo});
const initialLessonsState = adapter.getInitialState();
export function lessonsReducer(
state = initialLessonsState,
action: Lessonctions): LessonsState {
switch(action.type) {
case CourseActionTypes.LESSON_LOADED:
return adapter.addOne(action.payload.course, state);
default:
return state;
}
}
export const {
selectAll,
selectEntities,
selectIds,
selectTotal
} = adapter.getSelectors();
export const adapter : EntityAdapter<Lesson> =
createEntityAdapter<Lesson>({
sortComparer: sortBySeqNo,
selectId: lesson => lesson.courseId + '-' + lesson.seqNo
});
export interface CoursesState extends EntityState<Course> {
allCoursesLoaded:boolean;
}
export const adapter : EntityAdapter<Course> =
createEntityAdapter<Course>();
export const initialCoursesState: CoursesState =
adapter.getInitialState({
allCoursesLoaded: false
});
export function coursesReducer(
state = initialCoursesState ,
action: CourseActions): CoursesState {
switch(action.type) {
case CourseActionTypes.COURSE_LOADED:
return adapter.addOne(action.payload.course, state);
case CourseActionTypes.ALL_COURSES_LOADED:
return adapter.addAll(
action.payload.courses, {
...state,
allCoursesLoaded:true
});
default: {
return state;
}
}
}
export const {
selectAll,
selectEntities,
selectIds,
selectTotal
} = adapter.getSelectors();
export interface Lesson {
id: string;
}
export enum LessonActionTypes {
LoadLessons = '[Lesson] Load Lessons',
AddLesson = '[Lesson] Add Lesson',
UpsertLesson = '[Lesson] Upsert Lesson',
AddLessons = '[Lesson] Add Lessons',
UpsertLessons = '[Lesson] Upsert Lessons',
UpdateLesson = '[Lesson] Update Lesson',
UpdateLessons = '[Lesson] Update Lessons',
DeleteLesson = '[Lesson] Delete Lesson',
DeleteLessons = '[Lesson] Delete Lessons',
ClearLessons = '[Lesson] Clear Lessons'
}
export class LoadLessons implements Action {
readonly type = LessonActionTypes.LoadLessons;
constructor(public payload: { lessons: Lesson[] }) {}
}
export class AddLesson implements Action {
readonly type = LessonActionTypes.AddLesson;
constructor(public payload: { lesson: Lesson }) {}
}
export class UpsertLesson implements Action {
readonly type = LessonActionTypes.UpsertLesson;
constructor(public payload: { lesson: Lesson }) {}
}
export class AddLessons implements Action {
readonly type = LessonActionTypes.AddLessons;
constructor(public payload: { lessons: Lesson[] }) {}
}
export class UpsertLessons implements Action {
readonly type = LessonActionTypes.UpsertLessons;
constructor(public payload: { lessons: Lesson[] }) {}
}
export class UpdateLesson implements Action {
readonly type = LessonActionTypes.UpdateLesson;
constructor(public payload: { lesson: Update<Lesson> }) {}
}
export class UpdateLessons implements Action {
readonly type = LessonActionTypes.UpdateLessons;
constructor(public payload: { lessons: Update<Lesson>[] }) {}
}
export class DeleteLesson implements Action {
readonly type = LessonActionTypes.DeleteLesson;
constructor(public payload: { id: string }) {}
}
export class DeleteLessons implements Action {
readonly type = LessonActionTypes.DeleteLessons;
constructor(public payload: { ids: string[] }) {}
}
export class ClearLessons implements Action {
readonly type = LessonActionTypes.ClearLessons;
}
export type LessonActions =
LoadLessons
| AddLesson
| UpsertLesson
| AddLessons
| UpsertLessons
| UpdateLesson
| UpdateLessons
| DeleteLesson
| DeleteLessons
| ClearLessons;
export interface State extends EntityState<Lesson> {
}
export const adapter: EntityAdapter<Lesson> =
createEntityAdapter<Lesson>();
export const initialState: State =
adapter.getInitialState({});
export function reducer(
state = initialState,
action: LessonActions
): State {
switch (action.type) {
case LessonActionTypes.AddLesson: {
return adapter.addOne(action.payload.lesson, state);
}
case LessonActionTypes.UpsertLesson: {
return adapter.upsertOne(action.payload.lesson, state);
}
case LessonActionTypes.AddLessons: {
return adapter.addMany(action.payload.lessons, state);
}
case LessonActionTypes.UpsertLessons: {
return adapter.upsertMany(action.payload.lessons, state);
}
case LessonActionTypes.UpdateLesson: {
return adapter.updateOne(action.payload.lesson, state);
}
case LessonActionTypes.UpdateLessons: {
return adapter.updateMany(action.payload.lessons, state);
}
case LessonActionTypes.DeleteLesson: {
return adapter.removeOne(action.payload.id, state);
}
case LessonActionTypes.DeleteLessons: {
return adapter.removeMany(action.payload.ids, state);
}
case LessonActionTypes.LoadLessons: {
return adapter.addAll(action.payload.lessons, state);
}
case LessonActionTypes.ClearLessons: {
return adapter.removeAll(state);
}
default: {
return state;
}
}
}
export const {
selectIds,
selectEntities,
selectAll,
selectTotal,
} = adapter.getSelectors();
const update: Update<Course> = {
id: 1,
changes: {
description: "NgRx In Depth",
category: 'INTERMEDIATE'
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment