2 |
3 |
4 | You must enter a name
5 |
6 |
7 |
8 | You must enter a url
9 |
10 |
11 |
12 |
13 | {{ item }}
14 |
15 |
16 | You must select a group
17 |
18 |
19 |
20 |
26 | Add
27 |
28 | Cancel
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/app/service/bookmark.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 |
3 | import { BookmarkService } from './bookmark.service';
4 | import { HttpClientTestingModule } from '@angular/common/http/testing';
5 | import { HttpClient } from '@angular/common/http';
6 |
7 | describe('BookmarkService', () => {
8 | let httpClient: HttpClient;
9 | let service: BookmarkService;
10 |
11 | beforeEach(() => {
12 | TestBed.configureTestingModule({
13 | imports: [HttpClientTestingModule],
14 | });
15 | service = TestBed.get(BookmarkService);
16 | httpClient = TestBed.get(HttpClient);
17 | });
18 |
19 | it('should be created', async () => {
20 | spyOn(httpClient, 'post').and.callThrough();
21 | await service.createBookmark(null);
22 | expect(service).toBeTruthy();
23 | expect(httpClient.post).toHaveBeenCalled();
24 | });
25 |
26 | it('should be deleted', async () => {
27 | spyOn(httpClient, 'delete').and.callThrough();
28 | await service.deleteBookmark('12');
29 | expect(service).toBeTruthy();
30 | expect(httpClient.delete).toHaveBeenCalled();
31 | });
32 |
33 | it('should be fetched', async () => {
34 | spyOn(httpClient, 'get').and.callThrough();
35 | await service.getBookmarks();
36 | expect(service).toBeTruthy();
37 | expect(httpClient.get).toHaveBeenCalled();
38 | });
39 | });
40 |
--------------------------------------------------------------------------------
/src/app/add-bookmark/add-bookmark.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { Store } from '@ngrx/store';
4 | import { Bookmark } from '../bookmark/bookmark-interface';
5 | import { BookmarkService } from '../service/bookmark.service';
6 | import * as BookmarkActions from '../store/bookmark.actions';
7 | import { FormControl, Validators } from '@angular/forms';
8 | import { BOOKMARK_GROUPS } from '../shared/constant';
9 |
10 | @Component({
11 | selector: 'app-add-bookmark',
12 | templateUrl: './add-bookmark.component.html',
13 | styleUrls: ['./add-bookmark.component.css'],
14 | })
15 | export class AddBookmarkComponent implements OnInit {
16 | bookmarkName = new FormControl('', [Validators.required]);
17 | bookmarkUrl = new FormControl('', [Validators.required]);
18 | bookmarkGroup = new FormControl('', [Validators.required]);
19 |
20 | constructor(private store: Store, private router: Router) {}
21 | ngOnInit() {}
22 |
23 | createBookmark() {
24 | const newBookmark: Bookmark = { id: '', name: '', url: '', group: '' };
25 | newBookmark.name = this.bookmarkName.value;
26 | newBookmark.url = this.bookmarkUrl.value;
27 | newBookmark.group = this.bookmarkGroup.value;
28 |
29 | this.store.dispatch(new BookmarkActions.CreateBookmark(newBookmark));
30 | this.router.navigate(['/']);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/app/store/bookmark.actions.ts:
--------------------------------------------------------------------------------
1 | import { Action } from '@ngrx/store';
2 | import { Bookmark } from '../bookmark/bookmark-interface';
3 |
4 | export enum BookmarkActionTypes {
5 | LoadBookmarks = '[Bookmark] Load Bookmarks',
6 | LoadBookmarksSuccess = '[Bookmark] Load Bookmarks Success',
7 | LoadBookmarksFailure = '[Bookmark] Load Bookmarks Failure',
8 | DeleteBookmarks = '[Bookmark] Delete Bookmark',
9 | CreateBookmark = '[Bookmark] create Bookmark',
10 | }
11 |
12 | export class LoadBookmarks implements Action {
13 | readonly type = BookmarkActionTypes.LoadBookmarks;
14 | }
15 |
16 | export class LoadBookmarksSuccess implements Action {
17 | readonly type = BookmarkActionTypes.LoadBookmarksSuccess;
18 | constructor(public payload: { data: Bookmark[] }) {}
19 | }
20 |
21 | export class LoadBookmarksFailure implements Action {
22 | readonly type = BookmarkActionTypes.LoadBookmarksFailure;
23 | constructor(public payload: { error: any }) {}
24 | }
25 |
26 | export class DeleteBookmarks implements Action {
27 | readonly type = BookmarkActionTypes.DeleteBookmarks;
28 | constructor(public payload: string) {}
29 | }
30 |
31 | export class CreateBookmark implements Action {
32 | readonly type = BookmarkActionTypes.CreateBookmark;
33 | constructor(public payload: Bookmark) {}
34 | }
35 |
36 | export type BookmarkActions = LoadBookmarks | LoadBookmarksSuccess | LoadBookmarksFailure | DeleteBookmarks | CreateBookmark;
37 |
--------------------------------------------------------------------------------
/src/app/store/bookmark.reducer.ts:
--------------------------------------------------------------------------------
1 | import { Action } from '@ngrx/store';
2 | import { Bookmark } from '../bookmark/bookmark-interface';
3 | import { BookmarkActions, BookmarkActionTypes } from './bookmark.actions';
4 |
5 | export const bookmarkFeatureKey = 'bookmark';
6 |
7 | export interface State {
8 | bookmark: Bookmark[];
9 | error: string;
10 | }
11 |
12 | export const initialState: State = {
13 | bookmark: [],
14 | error: '',
15 | };
16 |
17 | export function reducer(state = initialState, action: BookmarkActions): State {
18 | switch (action.type) {
19 | case BookmarkActionTypes.LoadBookmarks:
20 | return {
21 | ...state,
22 | };
23 |
24 | case BookmarkActionTypes.LoadBookmarksSuccess:
25 | return {
26 | ...state,
27 | bookmark: action.payload.data,
28 | error: '',
29 | };
30 |
31 | case BookmarkActionTypes.LoadBookmarksFailure:
32 | return {
33 | ...state,
34 | bookmark: [],
35 | error: action.payload.error,
36 | };
37 |
38 | case BookmarkActionTypes.CreateBookmark:
39 | return {
40 | ...state,
41 | bookmark: [action.payload],
42 | error: '',
43 | };
44 |
45 | case BookmarkActionTypes.DeleteBookmarks:
46 | return {
47 | ...state,
48 | bookmark: state.bookmark.filter((item) => item.id !== action.payload),
49 | error: '',
50 | };
51 | default:
52 | return state;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/app/bookmark/bookmark.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, OnChanges, OnInit } from '@angular/core';
2 | import { select } from '@ngrx/store';
3 | import { Store } from '@ngrx/store';
4 | import { Bookmark } from './bookmark-interface';
5 | import * as BookmarkActions from '../store/bookmark.actions';
6 | import * as BookmarkSelector from '../store/bookmark.selectors';
7 | import { BookmarkService } from '../service/bookmark.service';
8 |
9 | @Component({
10 | selector: 'app-bookmark',
11 | templateUrl: './bookmark.component.html',
12 | styleUrls: ['./bookmark.component.css'],
13 | })
14 | export class BookmarkComponent implements OnChanges {
15 | filteredBookmarks: Bookmark[];
16 | errorMessage = '';
17 | @Input() groupName: string;
18 |
19 | constructor(private store: Store, private service: BookmarkService) {}
20 |
21 | ngOnChanges() {
22 | this.getBookmarks();
23 | }
24 |
25 | getBookmarks() {
26 | /* this.service.getBookmarks().subscribe(data=>{
27 | let bookmarks=data;
28 | this.filteredBookmarks = bookmarks.filter(ele=>ele.group==this.groupName)
29 | }) */
30 |
31 | this.store.dispatch(new BookmarkActions.LoadBookmarks()); // action dispatch
32 |
33 | this.store.pipe(select(BookmarkSelector.getBookmarks)).subscribe((ele) => {
34 | const bookmarks = ele;
35 | this.filteredBookmarks = bookmarks.filter((data) => data.group === this.groupName);
36 | });
37 |
38 | this.store.pipe(select(BookmarkSelector.getError)).subscribe((err) => {
39 | this.errorMessage = err;
40 | });
41 | }
42 |
43 | deleteBookmark(bookmarkId) {
44 | this.store.dispatch(new BookmarkActions.DeleteBookmarks(bookmarkId));
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/app/store/bookmark.effects.ts:
--------------------------------------------------------------------------------
1 | import {Injectable} from '@angular/core';
2 | import {Actions, Effect, ofType} from '@ngrx/effects';
3 | import {Action} from '@ngrx/store';
4 | import * as BookmarkActions from './bookmark.actions';
5 | import {CreateBookmark, DeleteBookmarks} from './bookmark.actions';
6 | import {Observable, of} from 'rxjs';
7 | import {catchError, map, mergeMap, switchMap} from 'rxjs/operators';
8 | import {BookmarkService} from '../service/bookmark.service';
9 |
10 | @Injectable()
11 | export class BookmarkEffects {
12 | constructor(private actions$: Actions, private bookmarkService: BookmarkService) {}
13 |
14 | @Effect()
15 | loadBookmarks$: Observable