diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 285be48..08b7925 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -5,7 +5,6 @@ import { HeaderComponent } from "./header/header.component"; import { HomeComponent } from "./home/home.component"; import { SharedModule } from "../shared/shared.module"; import { AppRoutingModule } from "../app-routing.module"; -import { ShoppingListService } from "../shopping-list/shopping-list.service"; import { RecipeService } from "../recipes/recipe.service"; import { DataStorageService } from "../shared/data-storage.service"; import { AuthService } from "../auth/auth.service"; @@ -26,7 +25,6 @@ import { LoggingInterceptor } from "../shared/logging.interceptor"; HeaderComponent ], providers: [ - ShoppingListService, RecipeService, DataStorageService, AuthService, diff --git a/src/app/recipes/recipe-detail/recipe-detail.component.ts b/src/app/recipes/recipe-detail/recipe-detail.component.ts index 2239be4..96c211b 100644 --- a/src/app/recipes/recipe-detail/recipe-detail.component.ts +++ b/src/app/recipes/recipe-detail/recipe-detail.component.ts @@ -1,8 +1,11 @@ import { Component, OnInit } from '@angular/core'; import { Router, ActivatedRoute, Params } from '@angular/router'; +import { Store } from '@ngrx/store'; import { Recipe } from '../recipe.model'; import { RecipeService } from '../recipe.service'; +import * as ShoppingListActions from '../../shopping-list/ngrx/shopping-list.actions'; +import * as fromShoppingList from '../../shopping-list/ngrx/shopping-list.reducers'; @Component({ selector: 'app-recipe-detail', @@ -15,7 +18,8 @@ export class RecipeDetailComponent implements OnInit { constructor(private recipeService: RecipeService, private route: ActivatedRoute, - private router: Router) { } + private router: Router, + private store: Store) { } ngOnInit() { this.route.params.subscribe( @@ -27,7 +31,7 @@ export class RecipeDetailComponent implements OnInit { } onAddToShoppingList() { - this.recipeService.addIngredientsToShoppingList(this.recipe.ingredients); + this.store.dispatch(new ShoppingListActions.AddIngredients(this.recipe.ingredients)); } onEditRecipe() { diff --git a/src/app/recipes/recipe.service.ts b/src/app/recipes/recipe.service.ts index d2a7c47..cecd1ae 100644 --- a/src/app/recipes/recipe.service.ts +++ b/src/app/recipes/recipe.service.ts @@ -1,17 +1,13 @@ +import { EventEmitter } from "@angular/core"; +import { Subject } from "rxjs/Subject"; + import { Recipe } from "./recipe.model"; -import { EventEmitter, Injectable } from "@angular/core"; import { Ingredient } from "../shared/ingredient.model"; -import { ShoppingListService } from "../shopping-list/shopping-list.service"; -import { Subject } from "rxjs/Subject"; -import { nextTick } from "q"; -@Injectable() export class RecipeService { recipesChanged = new Subject(); private recipes: Recipe[] = []; - constructor(private shoppingListService: ShoppingListService) { } - replaceRecipes(recipes: Recipe[]) { this.recipes = recipes; this.recipesChanged.next(this.recipes.slice()); @@ -25,10 +21,6 @@ export class RecipeService { return this.recipes[index]; } - addIngredientsToShoppingList(ingredients: Ingredient[]) { - this.shoppingListService.addIngredients(ingredients); - } - addRecipe(recipe: Recipe) { this.recipes.push(recipe); this.recipesChanged.next(this.recipes.slice()); diff --git a/src/app/shopping-list/ngrx/shopping-list.actions.ts b/src/app/shopping-list/ngrx/shopping-list.actions.ts index d755ecc..6ea1850 100644 --- a/src/app/shopping-list/ngrx/shopping-list.actions.ts +++ b/src/app/shopping-list/ngrx/shopping-list.actions.ts @@ -3,6 +3,11 @@ import { Action } from '@ngrx/store'; import { Ingredient } from '../../shared/ingredient.model'; export const ADD_INGREDIENT = 'ADD_INGREDIENT'; +export const ADD_INGREDIENTS = 'ADD_INGREDIENTS'; +export const UPDATE_INGREDIENT = 'UPDATE_INGREDIENT'; +export const DELETE_INGREDIENT = 'DELETE_INGREDIENT'; +export const START_EDIT = 'START_EDIT'; +export const STOP_EDIT = 'STOP_EDIT'; export class AddIngredient implements Action { readonly type = ADD_INGREDIENT; @@ -10,4 +15,32 @@ export class AddIngredient implements Action { constructor(public payload: Ingredient) {} } -export type ShoppingListActions = AddIngredient; \ No newline at end of file +export class AddIngredients implements Action { + readonly type = ADD_INGREDIENTS; + + constructor(public payload: Ingredient[]) {} +} + +export class UpdateIngredient implements Action { + readonly type = UPDATE_INGREDIENT; + + constructor(public payload: Ingredient) {} +} + +export class DeleteIngredient implements Action { + readonly type = DELETE_INGREDIENT; +} + +export class StartEdit implements Action { + readonly type = START_EDIT; + + constructor(public payload: number) {} +} + +export class StopEdit implements Action { + readonly type = STOP_EDIT; +} + + + +export type ShoppingListActions = AddIngredient | AddIngredients | UpdateIngredient | DeleteIngredient | StartEdit | StopEdit; \ No newline at end of file diff --git a/src/app/shopping-list/ngrx/shopping-list.reducers.ts b/src/app/shopping-list/ngrx/shopping-list.reducers.ts index ee47e22..d9d234d 100644 --- a/src/app/shopping-list/ngrx/shopping-list.reducers.ts +++ b/src/app/shopping-list/ngrx/shopping-list.reducers.ts @@ -2,12 +2,27 @@ import * as ShoppingListActions from './shopping-list.actions'; import { Ingredient } from '../../shared/ingredient.model'; +export interface AppState { + shoppingList: State +} + +export interface State { + ingredients: Ingredient[]; + editedIngredient: Ingredient; + editedIngredientIndex: number; +} + export const ADD_INGREDIENT = 'ADD_INGREDIENT'; +export const ADD_INGREDIENTS = 'ADD_INGREDIENTS'; +export const UPDATE_INGREDIENT = 'UPDATE_INGREDIENT'; +export const DELETE_INGREDIENT = 'DELETE_INGREDIENT'; -const initialState = { +const initialState: State = { ingredients: [ new Ingredient('Banana', 10) - ] + ], + editedIngredient: null, + editedIngredientIndex: -1 }; export function shoppingListReducer(state = initialState, action: ShoppingListActions.ShoppingListActions) { @@ -17,6 +32,47 @@ export function shoppingListReducer(state = initialState, action: ShoppingListAc ...state, ingredients: [...state.ingredients, action.payload] }; + case ShoppingListActions.ADD_INGREDIENTS: + return { + ...state, + ingredients: [...state.ingredients, ...action.payload] + }; + case ShoppingListActions.UPDATE_INGREDIENT: + const ingredient = state.ingredients[state.editedIngredientIndex]; + const updatedIngredient = { + ...ingredient, + ...action.payload + } + const ingredients = [...state.ingredients]; + ingredients[state.editedIngredientIndex] = updatedIngredient; + return { + ...state, + ingredients: ingredients, + editedIngredient: null, + editedIngredientIndex: -1 + }; + case ShoppingListActions.DELETE_INGREDIENT: + const oldIngredients = [...state.ingredients]; + oldIngredients.splice(state.editedIngredientIndex, 1); + return { + ...state, + ingredients: oldIngredients, + editedIngredient: null, + editedIngredientIndex: -1 + }; + case ShoppingListActions.START_EDIT: + const editedIngredient = {...state.ingredients[action.payload]}; + return { + ...state, + editedIngredient: editedIngredient, + editedIngredientIndex: action.payload + } + case ShoppingListActions.STOP_EDIT: + return { + ...state, + editedIngredient: null, + editedIngredientIndex: -1 + } default: return state; } diff --git a/src/app/shopping-list/shopping-edit/shopping-edit.component.ts b/src/app/shopping-list/shopping-edit/shopping-edit.component.ts index 240161b..198040e 100644 --- a/src/app/shopping-list/shopping-edit/shopping-edit.component.ts +++ b/src/app/shopping-list/shopping-edit/shopping-edit.component.ts @@ -4,8 +4,8 @@ import { Subscription } from 'rxjs/Subscription'; import { Store } from '@ngrx/store'; import { Ingredient } from '../../shared/ingredient.model'; -import { ShoppingListService } from '../shopping-list.service'; import * as ShoppingListActions from '../ngrx/shopping-list.actions'; +import * as fromShoppingList from '../ngrx/shopping-list.reducers'; @Component({ selector: 'app-shopping-edit', @@ -16,22 +16,23 @@ export class ShoppingEditComponent implements OnInit, OnDestroy { @ViewChild('f') shoppingListForm: NgForm; subscription: Subscription editMode = false; - editedItemIndex: number; editedItem: Ingredient; - constructor(private shoppingListService: ShoppingListService, - private store: Store<{shoppingList: {ingredients: Ingredient[]}}>) { } + constructor(private store: Store) { } ngOnInit() { - this.subscription = this.shoppingListService.startedEditing.subscribe( - (index: number) => { - this.editedItemIndex = index; - this.editMode = true; - this.editedItem = this.shoppingListService.getIngredient(index); - this.shoppingListForm.setValue({ - name: this.editedItem.name, - amount: this.editedItem.amount - }) + this.subscription = this.store.select('shoppingList').subscribe( + data => { + if (data.editedIngredientIndex > -1) { + this.editedItem = data.editedIngredient; + this.editMode = true; + this.shoppingListForm.setValue({ + name: this.editedItem.name, + amount: this.editedItem.amount + }) + } else { + this.editMode = false; + } } ); } @@ -40,7 +41,7 @@ export class ShoppingEditComponent implements OnInit, OnDestroy { const value = form.value const newIngredient = new Ingredient(value.name, value.amount); if (this.editMode) { - this.shoppingListService.updateIngredient(this.editedItemIndex, newIngredient); + this.store.dispatch(new ShoppingListActions.UpdateIngredient(newIngredient)); } else { this.store.dispatch(new ShoppingListActions.AddIngredient(newIngredient)); } @@ -54,11 +55,12 @@ export class ShoppingEditComponent implements OnInit, OnDestroy { } onDelete() { - this.shoppingListService.deleteIngredient(this.editedItemIndex); + this.store.dispatch(new ShoppingListActions.DeleteIngredient()); this.onClear(); } ngOnDestroy() { + this.store.dispatch(new ShoppingListActions.StopEdit()); this.subscription.unsubscribe(); } } diff --git a/src/app/shopping-list/shopping-list.component.ts b/src/app/shopping-list/shopping-list.component.ts index 772cbcd..9c865d8 100644 --- a/src/app/shopping-list/shopping-list.component.ts +++ b/src/app/shopping-list/shopping-list.component.ts @@ -3,7 +3,8 @@ import { Store } from '@ngrx/store'; import { Observable } from 'rxjs/Observable'; import { Ingredient } from '../shared/ingredient.model'; -import { ShoppingListService } from './shopping-list.service'; +import * as ShoppingListActions from './ngrx/shopping-list.actions'; +import * as fromShoppingList from './ngrx/shopping-list.reducers'; @Component({ selector: 'app-shopping-list', @@ -13,14 +14,13 @@ import { ShoppingListService } from './shopping-list.service'; export class ShoppingListComponent implements OnInit { shoppingListState: Observable<{ingredients: Ingredient[]}>; - constructor(private shoppingListService: ShoppingListService, - private store: Store<{shoppingList: {ingredients: Ingredient[]}}>) { } + constructor(private store: Store) { } ngOnInit() { this.shoppingListState = this.store.select('shoppingList'); } onEditItem(index: number) { - this.shoppingListService.startedEditing.next(index); + this.store.dispatch(new ShoppingListActions.StartEdit(index)); } } diff --git a/src/app/shopping-list/shopping-list.service.ts b/src/app/shopping-list/shopping-list.service.ts deleted file mode 100644 index 626a4dc..0000000 --- a/src/app/shopping-list/shopping-list.service.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Ingredient } from "../shared/ingredient.model"; -import { Subject } from "rxjs/Subject"; - -export class ShoppingListService { - ingredientsChanged = new Subject(); - startedEditing = new Subject(); - private ingredients: Ingredient[] = []; - - getIngredient(index: number) { - return this.ingredients[index]; - } - - addIngredients(ingredients: Ingredient[]) { - this.ingredients.push(...ingredients); - this.ingredientsChanged.next(this.ingredients.slice()); - } - - updateIngredient(index: number, newIngredient: Ingredient) { - this.ingredients[index] = newIngredient; - this.ingredientsChanged.next(this.ingredients.slice()); - } - - deleteIngredient(index: number) { - this.ingredients.splice(index, 1); - this.ingredientsChanged.next(this.ingredients.slice()); - } -} \ No newline at end of file