Skip to content

Commit f96974f

Browse files
King-itimdeschryver
authored andcommitted
refactor(example): remove @ngrx/db (#1664)
Closes #1481
1 parent c7e1406 commit f96974f

File tree

13 files changed

+281
-76
lines changed

13 files changed

+281
-76
lines changed

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@
9494
"@angular/router": "^7.0.1",
9595
"@applitools/eyes-cypress": "^3.4.12",
9696
"@bazel/buildifier": "^0.22.0",
97-
"@ngrx/db": "^2.2.0-beta.0",
9897
"core-js": "^2.5.4",
9998
"hammerjs": "^2.0.8",
10099
"opencollective": "^1.0.3",

projects/example-app-cypress/integration/round-trip.spec.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,18 @@ context('Full round trip', () => {
55
testName: 'round-trip',
66
browser: { width: 800, height: 600 },
77
});
8-
window.indexedDB.deleteDatabase('books_app');
8+
window.localStorage.removeItem('books_app');
99
cy.visit('/');
1010
});
1111

12+
beforeEach(() => {
13+
(cy as any).restoreLocalStorage();
14+
});
15+
16+
afterEach(() => {
17+
(cy as any).saveLocalStorage();
18+
});
19+
1220
after(() => {
1321
(cy as any).eyesClose();
1422
});
Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1-
import'@applitools/eyes-cypress/commands';
1+
import '@applitools/eyes-cypress/commands';
22

3+
let LOCAL_STORAGE_MEMORY = {};
34

5+
Cypress.Commands.add('saveLocalStorage', () => {
6+
Object.keys(localStorage).forEach(key => {
7+
LOCAL_STORAGE_MEMORY[key] = localStorage[key];
8+
});
9+
});
10+
11+
Cypress.Commands.add('restoreLocalStorage', () => {
12+
Object.keys(LOCAL_STORAGE_MEMORY).forEach(key => {
13+
localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]);
14+
});
15+
});

projects/example-app/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
Example application utilizing @ngrx libraries, showcasing common patterns and best practices. Try it on [StackBlitz](https://ngrx.github.io/platform/stackblitz.html).
44

55
This app is a book collection manager. The user can authenticate, use the Google Books API to search for
6-
books and add them to their collection. This application utilizes [@ngrx/db](https://github.com/ngrx/db)
7-
to persist the collection across sessions; [@ngrx/store](../../docs/store/README.md) to manage
6+
books and add them to their collection. This application utilizes [@ngrx/store](../../docs/store/README.md to manage
87
the state of the app and to cache requests made to the Google Books API;
98
[@ngrx/effects](../../docs/effects/README.md) to isolate side effects; [@angular/router](https://github.com/angular/angular) to manage navigation between routes; [@angular/material](https://github.com/angular/material2) to provide design and styling.
109

@@ -17,7 +16,6 @@ Built with [@angular/cli](https://github.com/angular/angular-cli)
1716
- [@ngrx/router-store](../../docs/router-store/README.md) - Bindings to connect the Angular Router to @ngrx/store
1817
- [@ngrx/entity](../../docs/entity/README.md) - Entity State adapter for managing record collections.
1918
- [@ngrx/store-devtools](../../docs/store-devtools/README.md) - Instrumentation for @ngrx/store enabling time-travel debugging
20-
- [@ngrx/db](https://github.com/ngrx/db) - RxJS powered IndexedDB for Angular apps
2119
- [@angular/router](https://github.com/angular/angular) - Angular Router
2220
- [@angular/material](https://github.com/angular/material2) - Angular Material
2321
- [jest](https://facebook.github.io/jest/) - JavaScript test runner with easy setup, isolated browser testing and snapshot testing

projects/example-app/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module.exports = {
1616
mapCoverage: true,
1717
coveragePathIgnorePatterns: ['/node_modules/', '/modules/*.*/'],
1818
moduleNameMapper: {
19-
'^@ngrx/(?!db)(.*)': '<rootDir>/../../modules/$1',
19+
'^@ngrx/(.*)': '<rootDir>/../../modules/$1',
2020
'^@example-app/(.*)': '<rootDir>/src/app/$1',
2121
},
2222
transformIgnorePatterns: ['node_modules/(?!@ngrx)'],

projects/example-app/src/app/app.module.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
66

77
import { StoreModule } from '@ngrx/store';
88
import { EffectsModule } from '@ngrx/effects';
9-
import { DBModule } from '@ngrx/db';
109
import { StoreRouterConnectingModule } from '@ngrx/router-store';
1110
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
1211

1312
import { CoreModule } from '@example-app/core/core.module';
1413
import { AuthModule } from '@example-app/auth/auth.module';
1514

1615
import { reducers, metaReducers } from '@example-app/reducers';
17-
import { schema } from '@example-app/db';
1816

1917
import { AppComponent } from '@example-app/core/containers/app.component';
2018
import { AppRoutingModule } from '@example-app/app-routing.module';
@@ -68,12 +66,6 @@ import { AppRoutingModule } from '@example-app/app-routing.module';
6866
*/
6967
EffectsModule.forRoot([]),
7068

71-
/**
72-
* `provideDB` sets up @ngrx/db with the provided schema and makes the Database
73-
* service available.
74-
*/
75-
DBModule.provideDB(schema),
76-
7769
CoreModule,
7870
],
7971
bootstrap: [AppComponent],

projects/example-app/src/app/books/effects/collection.effects.spec.ts

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { TestBed } from '@angular/core/testing';
2-
import { Database } from '@ngrx/db';
32
import { Actions } from '@ngrx/effects';
43
import { provideMockActions } from '@ngrx/effects/testing';
54
import { cold, hot } from 'jasmine-marbles';
@@ -12,6 +11,10 @@ import {
1211
} from '@example-app/books/actions';
1312
import { Book } from '@example-app/books/models/book';
1413
import { CollectionEffects } from '@example-app/books/effects/collection.effects';
14+
import {
15+
BookStorageService,
16+
LOCAL_STORAGE_TOKEN,
17+
} from '@example-app/core/services/';
1518

1619
describe('CollectionEffects', () => {
1720
let db: any;
@@ -26,30 +29,37 @@ describe('CollectionEffects', () => {
2629
providers: [
2730
CollectionEffects,
2831
{
29-
provide: Database,
32+
provide: BookStorageService,
33+
useValue: {
34+
supported: jest.fn(),
35+
deleteStoredCollection: jest.fn(),
36+
addToCollection: jest.fn(),
37+
getCollection: jest.fn(),
38+
removeFromCollection: jest.fn(),
39+
},
40+
},
41+
{
42+
provide: LOCAL_STORAGE_TOKEN,
3043
useValue: {
31-
open: jest.fn(),
32-
query: jest.fn(),
33-
insert: jest.fn(),
34-
executeWrite: jest.fn(),
44+
removeItem: jest.fn(),
45+
setItem: jest.fn(),
46+
getItem: jest.fn(_ => JSON.stringify([])),
3547
},
3648
},
3749
provideMockActions(() => actions$),
3850
],
3951
});
4052

41-
db = TestBed.get(Database);
53+
db = TestBed.get(BookStorageService);
4254
effects = TestBed.get(CollectionEffects);
4355
actions$ = TestBed.get(Actions);
4456
});
45-
46-
describe('openDB$', () => {
47-
it('should call db.open when initially subscribed to', () => {
48-
effects.openDB$.subscribe();
49-
expect(db.open).toHaveBeenCalledWith('books_app');
57+
describe('checkStorageSupport$', () => {
58+
it('should call db.checkStorageSupport when initially subscribed to', () => {
59+
effects.checkStorageSupport$.subscribe();
60+
expect(db.supported).toHaveBeenCalled();
5061
});
5162
});
52-
5363
describe('loadCollection$', () => {
5464
it('should return a collection.LoadSuccess, with the books, on success', () => {
5565
const action = CollectionPageActions.loadCollection();
@@ -58,9 +68,9 @@ describe('CollectionEffects', () => {
5868
});
5969

6070
actions$ = hot('-a', { a: action });
61-
const response = cold('-a-b|', { a: book1, b: book2 });
62-
const expected = cold('-----c', { c: completion });
63-
db.query = jest.fn(() => response);
71+
const response = cold('-a|', { a: [book1, book2] });
72+
const expected = cold('--c', { c: completion });
73+
db.getCollection = jest.fn(() => response);
6474

6575
expect(effects.loadCollection$).toBeObservable(expected);
6676
});
@@ -73,7 +83,7 @@ describe('CollectionEffects', () => {
7383
actions$ = hot('-a', { a: action });
7484
const response = cold('-#', {}, error);
7585
const expected = cold('--c', { c: completion });
76-
db.query = jest.fn(() => response);
86+
db.getCollection = jest.fn(() => response);
7787

7888
expect(effects.loadCollection$).toBeObservable(expected);
7989
});
@@ -87,10 +97,10 @@ describe('CollectionEffects', () => {
8797
actions$ = hot('-a', { a: action });
8898
const response = cold('-b', { b: true });
8999
const expected = cold('--c', { c: completion });
90-
db.insert = jest.fn(() => response);
100+
db.addToCollection = jest.fn(() => response);
91101

92102
expect(effects.addBookToCollection$).toBeObservable(expected);
93-
expect(db.insert).toHaveBeenCalledWith('books', [book1]);
103+
expect(db.addToCollection).toHaveBeenCalledWith([book1]);
94104
});
95105

96106
it('should return a collection.AddBookFail, with the book, when the db insert throws', () => {
@@ -101,7 +111,7 @@ describe('CollectionEffects', () => {
101111
actions$ = hot('-a', { a: action });
102112
const response = cold('-#', {}, error);
103113
const expected = cold('--c', { c: completion });
104-
db.insert = jest.fn(() => response);
114+
db.addToCollection = jest.fn(() => response);
105115

106116
expect(effects.addBookToCollection$).toBeObservable(expected);
107117
});
@@ -116,12 +126,10 @@ describe('CollectionEffects', () => {
116126
actions$ = hot('-a', { a: action });
117127
const response = cold('-b', { b: true });
118128
const expected = cold('--c', { c: completion });
119-
db.executeWrite = jest.fn(() => response);
129+
db.removeFromCollection = jest.fn(() => response);
120130

121131
expect(effects.removeBookFromCollection$).toBeObservable(expected);
122-
expect(db.executeWrite).toHaveBeenCalledWith('books', 'delete', [
123-
book1.id,
124-
]);
132+
expect(db.removeFromCollection).toHaveBeenCalledWith([book1.id]);
125133
});
126134

127135
it('should return a collection.RemoveBookFail, with the book, when the db insert throws', () => {
@@ -134,12 +142,10 @@ describe('CollectionEffects', () => {
134142
actions$ = hot('-a', { a: action });
135143
const response = cold('-#', {}, error);
136144
const expected = cold('--c', { c: completion });
137-
db.executeWrite = jest.fn(() => response);
145+
db.removeFromCollection = jest.fn(() => response);
138146

139147
expect(effects.removeBookFromCollection$).toBeObservable(expected);
140-
expect(db.executeWrite).toHaveBeenCalledWith('books', 'delete', [
141-
book1.id,
142-
]);
148+
expect(db.removeFromCollection).toHaveBeenCalledWith([book1.id]);
143149
});
144150
});
145151
});

projects/example-app/src/app/books/effects/collection.effects.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import { Injectable } from '@angular/core';
2-
import { Database } from '@ngrx/db';
32
import { Actions, Effect, ofType, createEffect } from '@ngrx/effects';
43
import { defer, of } from 'rxjs';
5-
import { catchError, map, mergeMap, switchMap, toArray } from 'rxjs/operators';
6-
4+
import { catchError, map, mergeMap, switchMap } from 'rxjs/operators';
75
import { Book } from '@example-app/books/models/book';
86
import {
9-
SelectedBookPageActions,
10-
CollectionPageActions,
117
CollectionApiActions,
8+
CollectionPageActions,
9+
SelectedBookPageActions,
1210
} from '@example-app/books/actions';
13-
11+
import { BookStorageService } from '@example-app/core/services';
1412
@Injectable()
1513
export class CollectionEffects {
1614
/**
@@ -24,16 +22,13 @@ export class CollectionEffects {
2422
* effect easier to test.
2523
*/
2624
@Effect({ dispatch: false })
27-
openDB$ = defer(() => {
28-
return this.db.open('books_app');
29-
});
25+
checkStorageSupport$ = defer(() => this.storageService.supported());
3026

3127
loadCollection$ = createEffect(() =>
3228
this.actions$.pipe(
3329
ofType(CollectionPageActions.loadCollection.type),
3430
switchMap(() =>
35-
this.db.query('books').pipe(
36-
toArray(),
31+
this.storageService.getCollection().pipe(
3732
map((books: Book[]) =>
3833
CollectionApiActions.loadBooksSuccess({ books })
3934
),
@@ -49,7 +44,7 @@ export class CollectionEffects {
4944
this.actions$.pipe(
5045
ofType(SelectedBookPageActions.addBook.type),
5146
mergeMap(({ book }) =>
52-
this.db.insert('books', [book]).pipe(
47+
this.storageService.addToCollection([book]).pipe(
5348
map(() => CollectionApiActions.addBookSuccess({ book })),
5449
catchError(() => of(CollectionApiActions.addBookFailure({ book })))
5550
)
@@ -61,7 +56,7 @@ export class CollectionEffects {
6156
this.actions$.pipe(
6257
ofType(SelectedBookPageActions.removeBook.type),
6358
mergeMap(({ book }) =>
64-
this.db.executeWrite('books', 'delete', [book.id]).pipe(
59+
this.storageService.removeFromCollection([book.id]).pipe(
6560
map(() => CollectionApiActions.removeBookSuccess({ book })),
6661
catchError(() => of(CollectionApiActions.removeBookFailure({ book })))
6762
)
@@ -73,6 +68,6 @@ export class CollectionEffects {
7368
private actions$: Actions<
7469
SelectedBookPageActions.SelectedBookPageActionsUnion
7570
>,
76-
private db: Database
71+
private storageService: BookStorageService
7772
) {}
7873
}

0 commit comments

Comments
 (0)