Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit a2f99cd

Browse files
authored
feat: support asyncresetDb; delay calling it until the first request (#135)
1 parent e8d1e7c commit a2f99cd

29 files changed

+620
-370
lines changed

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,17 @@ It is not supposed to emulate every possible real world web API and is not inten
66
We will make breaking changes and we won't feel bad about it
77
because this is a development tool, not a production product.
88
We do try to tell you about such changes in this `CHANGELOG.md`
9-
109
and we fix bugs as fast as we can.
1110

11+
<a id="0.4.2"></a>
12+
## 0.4.2 (2017-09-08)
13+
- Postpones the in-memory database initialization (via `resetDb`) until the first HTTP request.
14+
15+
- Your `createDb` method _can_ be asynchronous.
16+
You may return the database object (synchronous), an observable of it, or a promise of it. Issue #113.
17+
18+
- fixed some rare race conditions.
19+
1220
<a id="0.4.1"></a>
1321
## 0.4.1 (2017-09-08)
1422
**Support PassThru.**

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,19 @@ the in-memory backed provider supersedes the Angular version.
172172
export class AppModule { ... }
173173
```
174174

175-
### Examples
175+
* The `createDb` method can be synchronous or asynchronous.
176+
so you can initialize your in-memory database service from a JSON file.
177+
Return the database object, an observable of that object, or a promise of that object.
178+
The in-mem web api service calls `createDb` (a) when it handles the _first_ `HttpClient` (or `Http`) request and (b) when it receives a `POST resetdb` request.
179+
180+
## In-memory web api examples
176181
The tests (`src/app/*.spec.ts` files) in the [github repo](https://github.com/angular/in-memory-web-api/tree/master/src/app) are a good place to learn how to setup and use this in-memory web api library.
177182

178183
See also the example source code in the official Angular.io documentation such as the
179184
[HttpClient](https://angular.io/guide/http) guide and the
180185
[Tour of Heroes](https://angular.io/tutorial/toh-pt6).
181186

182-
# Bonus Features
187+
# Advanced Features
183188
Some features are not readily apparent in the basic usage example.
184189

185190
The `InMemoryBackendConfigArgs` defines a set of options. Add them as the second `forRoot` argument:
@@ -194,7 +199,7 @@ The `InMemoryBackendConfigArgs` defines a set of options. Add them as the second
194199
This service can evaluate requests in multiple ways depending upon the configuration.
195200
Here's how it reasons:
196201
1. If it looks like a [command](#commands), process as a command
197-
2. If the [HTTP method is overridden](#method-override)
202+
2. If the [HTTP method is overridden](#method-override), try the override.
198203
3. If the resource name (after the api base path) matches one of the configured collections, process that
199204
4. If not but the `Config.passThruUnknownUrl` flag is `true`, try to [pass the request along to a real _XHR_](#passthru).
200205
5. Return a 404.

backend.service.d.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Observable } from 'rxjs/Observable';
2-
import 'rxjs/add/operator/delay';
2+
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
33
import { HeadersCore, RequestInfoUtilities, InMemoryDbService, InMemoryBackendConfigArgs, ParsedRequestUrl, PassThruBackend, RequestCore, RequestInfo, ResponseOptions, UriInfo } from './interfaces';
44
/**
55
* Base class for in-memory web api back-ends
@@ -10,10 +10,12 @@ import { HeadersCore, RequestInfoUtilities, InMemoryDbService, InMemoryBackendCo
1010
*/
1111
export declare abstract class BackendService {
1212
protected inMemDbService: InMemoryDbService;
13-
protected passThruBackend: PassThruBackend;
1413
protected config: InMemoryBackendConfigArgs;
1514
protected db: Object;
15+
protected dbReadySubject: BehaviorSubject<boolean>;
16+
private passThruBackend;
1617
constructor(inMemDbService: InMemoryDbService, config?: InMemoryBackendConfigArgs);
18+
protected readonly dbReady: Observable<boolean>;
1719
/**
1820
* Process Request and return an Observable of Http Response object
1921
* in the manner of a RESTy web api.
@@ -39,6 +41,7 @@ export declare abstract class BackendService {
3941
* for this http library or null|undefined (which means "keep processing").
4042
*/
4143
protected handleRequest(req: RequestCore): Observable<any>;
44+
protected handleRequest_(req: RequestCore): Observable<any>;
4245
/**
4346
* Add configured delay to response observable unless delay === 0
4447
*/
@@ -80,6 +83,10 @@ export declare abstract class BackendService {
8083
protected abstract createHeaders(headers: {
8184
[index: string]: string;
8285
}): HeadersCore;
86+
/**
87+
* create the function that passes unhandled requests through to the "real" backend.
88+
*/
89+
protected abstract createPassThruBackend(): PassThruBackend;
8390
/**
8491
* return a search map from a location query/search string
8592
*/
@@ -99,7 +106,7 @@ export declare abstract class BackendService {
99106
* @param resOptionsFactory - creates ResponseOptions when observable is subscribed
100107
*/
101108
protected createResponseOptions$(resOptionsFactory: () => ResponseOptions): Observable<ResponseOptions>;
102-
protected delete({id, collection, collectionName, headers, url}: RequestInfo): ResponseOptions;
109+
protected delete(collection: any[], {id, collectionName, headers, url}: RequestInfo): ResponseOptions;
103110
/**
104111
* Find first instance of item in collection by `item.id`
105112
* @param collection
@@ -125,13 +132,18 @@ export declare abstract class BackendService {
125132
protected genIdDefault<T extends {
126133
id: any;
127134
}>(collection: T[]): any;
128-
protected get({id, query, collection, collectionName, headers, url}: RequestInfo): ResponseOptions;
135+
protected get(collection: any[], {id, query, collectionName, headers, url}: RequestInfo): ResponseOptions;
129136
/** Get JSON body from the request object */
130137
protected abstract getJsonBody(req: any): any;
131138
/**
132139
* Get location info from a url, even on server where `document` is not defined
133140
*/
134141
protected getLocation(url: string): UriInfo;
142+
/**
143+
* get or create the function that passes unhandled requests
144+
* through to the "real" backend.
145+
*/
146+
protected getPassThruBackend(): PassThruBackend;
135147
/**
136148
* return canonical HTTP method name (lowercase) from the request object
137149
* e.g. (req.method || 'get').toLowerCase();
@@ -140,9 +152,8 @@ export declare abstract class BackendService {
140152
*/
141153
protected abstract getRequestMethod(req: any): string;
142154
protected indexOf(collection: any[], id: number): number;
143-
protected parseId(collection: {
144-
id: any;
145-
}[], id: string): any;
155+
/** Parse the id as a number. Return original value if not a number. */
156+
protected parseId(id: string): any;
146157
/**
147158
* Parses the request URL into a `ParsedRequestUrl` object.
148159
* Parsing depends upon certain values of `config`: `apiBase`, `host`, and `urlRoot`.
@@ -161,18 +172,13 @@ export declare abstract class BackendService {
161172
* To replace this default method, assign your alternative to your InMemDbService['parseRequestUrl']
162173
*/
163174
protected parseRequestUrl(url: string): ParsedRequestUrl;
164-
protected post({collection, headers, id, req, resourceUrl, url}: RequestInfo): ResponseOptions;
165-
protected put({id, collection, collectionName, headers, req, url}: RequestInfo): ResponseOptions;
175+
protected post(collection: any[], {id, collectionName, headers, req, resourceUrl, url}: RequestInfo): ResponseOptions;
176+
protected put(collection: any[], {id, collectionName, headers, req, url}: RequestInfo): ResponseOptions;
166177
protected removeById(collection: any[], id: number): boolean;
167178
protected readonly requestInfoUtils: RequestInfoUtilities;
168179
/**
169-
* Reset the "database" to its original state
170-
*/
171-
protected resetDb(reqInfo?: RequestInfo): void;
172-
/**
173-
* Sets the function that passes unhandled requests
174-
* through to the "real" backend if
175-
* config.passThruUnknownUrl is true.
180+
* Tell your in-mem "database" to reset.
181+
* returns Observable of the database because resetting it could be async
176182
*/
177-
protected abstract setPassThruBackend(): void;
183+
protected resetDb(reqInfo?: RequestInfo): Observable<boolean>;
178184
}

0 commit comments

Comments
 (0)