diff --git a/README.MD b/README.MD index 06900cf7..878a5760 100644 --- a/README.MD +++ b/README.MD @@ -203,8 +203,14 @@ let posts = this.datastore.peekAll(Post); #### Retrieving a Single Record +Use `findOne()` to retrieve a record by its type and ID including metadata: +```typescript +this.datastore.findOne(Post, '1').subscribe( + (post: JsonApiQueryData) => console.log(post.getModel()) +); +``` -Use `findRecord()` to retrieve a record by its type and ID: +If you dont need Metadata you can use `findRecord()` to retrieve a record by its type and ID: ```typescript this.datastore.findRecord(Post, '1').subscribe( diff --git a/src/models/json-api-query-data.ts b/src/models/json-api-query-data.ts index 3ecee737..dfb222f5 100644 --- a/src/models/json-api-query-data.ts +++ b/src/models/json-api-query-data.ts @@ -1,11 +1,27 @@ export class JsonApiQueryData { - constructor(protected jsonApiModels: Array, protected metaData?: any) {} + constructor(protected data: Array | T, protected meta?: any) {} - public getModels(): T[] { - return this.jsonApiModels; + public getModels() : T[] { + if (!(this.data instanceof Array)) { + throw new Error('Data is not an array.'); + } + + return this.data; + } + + public getModel() : T { + if (this.data instanceof Array) { + throw new Error('Data is not an object.'); + } + + return this.data; + } + + public getData(): T[] | T { + return this.data; } public getMeta(): any { - return this.metaData; + return this.meta; } } diff --git a/src/services/json-api-datastore.service.spec.ts b/src/services/json-api-datastore.service.spec.ts index 7ec1cd00..a350c00b 100644 --- a/src/services/json-api-datastore.service.spec.ts +++ b/src/services/json-api-datastore.service.spec.ts @@ -294,6 +294,30 @@ describe('JsonApiDatastore', () => { }); }); + it('should get author with custom metadata', () => { + backend.connections.subscribe((c: MockConnection) => { + c.mockRespond(new Response( + new ResponseOptions({ + body: JSON.stringify({ + data: getAuthorData(), + meta: { + dates: { + generatedAt: 1518950882 + } + } + }) + }) + )); + }); + + datastore.findOne(Author, '1').subscribe((document) => { + expect(document.getModel()).toBeDefined(); + expect(document.getModel().id).toBe(AUTHOR_ID); + expect(document.getModel().date_of_birth).toEqual(parse(AUTHOR_BIRTH)); + expect(document.getMeta().meta.dates.generatedAt).toEqual(1518950882); + }); + }); + it('should generate correct query string for array params with findRecord', () => { backend.connections.subscribe((c: MockConnection) => { const decodedQueryString = decodeURI(c.request.url).split('?')[1]; diff --git a/src/services/json-api-datastore.service.ts b/src/services/json-api-datastore.service.ts index 6cb98855..89357f62 100644 --- a/src/services/json-api-datastore.service.ts +++ b/src/services/json-api-datastore.service.ts @@ -69,17 +69,39 @@ export class JsonApiDatastore { .catch((res: any) => this.handleError(res)); } - findRecord( + private fetchRecord( modelType: ModelType, id: string, params?: any, headers?: Headers, - customUrl?: string - ): Observable { + customUrl?: string, + ): Observable { const options: RequestOptions = this.getOptions(headers); const url: string = this.buildUrl(modelType, params, id, customUrl); - return this.http.get(url, options) + return this.http.get(url, options); + } + + findOne( + modelType: ModelType, + id: string, + params?: any, + headers?: Headers, + customUrl?: string + ): Observable> { + return this.fetchRecord(modelType, id, params, headers, customUrl) + .map((res) => this.extractRecordData(res, modelType, true)) + .catch((res: any) => this.handleError(res)); + } + + findRecord( + modelType: ModelType, + id: string, + params?: any, + headers?: Headers, + customUrl?: string + ): Observable { + return this.fetchRecord(modelType, id, params, headers, customUrl) .map((res) => this.extractRecordData(res, modelType)) .catch((res: any) => this.handleError(res)); } @@ -135,7 +157,11 @@ export class JsonApiDatastore { } return httpCall - .map((res) => [200, 201].indexOf(res.status) !== -1 ? this.extractRecordData(res, modelType, model) : model) + .map( + (res) => [200, 201].indexOf(res.status) !== -1 + ? this.extractRecordData(res, modelType, false, model) + : model + ) .catch((res) => { if (res == null) { return Observable.of(model); @@ -281,7 +307,12 @@ export class JsonApiDatastore { return new modelType(this, data); } - protected extractRecordData(res: Response, modelType: ModelType, model?: T): T { + protected extractRecordData( + res: Response, + modelType: ModelType, + withMeta = false, + model?: T + ): T | JsonApiQueryData { const body: any = res.json(); if (!body) { @@ -307,6 +338,10 @@ export class JsonApiDatastore { this.addToStore(deserializedModel); } + if (withMeta && withMeta === true) { + return new JsonApiQueryData(deserializedModel, this.parseMeta(body, modelType)); + } + return deserializedModel; }