Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"@angular/platform-browser-dynamic": "2.2.3",
"@angular/platform-server": "2.2.3",
"@types/jasmine": "2.5.38",
"@types/lodash": "^4.14.37",
"@types/lodash": "4.14.37",
"@types/reflect-metadata": "0.0.4",
"@types/selenium-webdriver": "^2.53.30",
"codelyzer": "~2.0.0-beta.1",
Expand Down
4 changes: 3 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ export * from './decorators/json-api-model-config.decorator';
export * from './decorators/json-api-datastore-config.decorator';

export * from './models/json-api.model';
export * from './models/document.model';
export * from './models/links.model';
export * from './models/link.model';
export * from './models/error-response.model';

export * from './providers';

export * from './module';

22 changes: 22 additions & 0 deletions src/models/document.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { LinksModel } from './links.model';

export class DocumentModel<T> {
private _links: LinksModel = new LinksModel;
private _data: T;

constructor(body: any) {
this._links.updateLinks(body.links);
}

get links() {
return this._links;
}

get data(): T {
return this._data;
}

set data(data: T) {
this._data = data;
}
}
11 changes: 10 additions & 1 deletion src/models/json-api.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@ import * as _ from 'lodash';
import { Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { JsonApiDatastore, ModelType } from '../services/json-api-datastore.service';
import { LinksModel } from './links.model';
import { LinkModel } from './link.model';
import { DocumentModel } from '../models/document.model';

export class JsonApiModel {

id: string;
private _links: LinksModel = new LinksModel;
[key: string]: any;

constructor(private _datastore: JsonApiDatastore, data?: any) {
if (data) {
this.id = data.id;
_.extend(this, data.attributes);
}
this._links.updateLinks(data.links);
}

get links() {
return this._links;
}

syncRelationships(data: any, included: any, level: number): void {
Expand All @@ -22,7 +31,7 @@ export class JsonApiModel {
}
}

save(params?: any, headers?: Headers): Observable<this> {
save(params?: any, headers?: Headers): Observable<DocumentModel<this>> {
let attributesMetadata: any = Reflect.getMetadata('Attribute', this);
return this._datastore.saveRecord(attributesMetadata, this, params, headers);
}
Expand Down
18 changes: 18 additions & 0 deletions src/models/link.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export class LinkModel {
private _name: string;
private _href: string;
// TODO: add meta

constructor(name: string, link: any) {
this._name = name;
this._href = link;
}

get name(): string {
return this._name;
}

get href(): string {
return this._href;
}
}
17 changes: 17 additions & 0 deletions src/models/links.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { LinkModel } from './link.model';

export class LinksModel {
[key: string]: any;

public updateLinks(links: any) {
// delete all properties of this object
Object.keys(this || {}).forEach((name) => {
delete this[name];
});

// assign new properties based on whats inside of links
Object.keys(links || {}).forEach((name) => {
this[name] = new LinkModel(name, links[name]);
});
}
}
26 changes: 18 additions & 8 deletions src/services/json-api-datastore.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@ import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { JsonApiModel } from '../models/json-api.model';
import { DocumentModel } from '../models/document.model';
import {ErrorResponse} from '../models/error-response.model';

export type ModelType<T extends JsonApiModel> = { new(datastore: JsonApiDatastore, data: any): T; };
export type ModelType<T extends JsonApiModel> = {
new(
datastore: JsonApiDatastore,
data: any
): T;
};

@Injectable()
export class JsonApiDatastore {
Expand All @@ -20,15 +26,15 @@ export class JsonApiDatastore {
constructor(private http: Http) {
}

query<T extends JsonApiModel>(modelType: ModelType<T>, params?: any, headers?: Headers): Observable<T[]> {
query<T extends JsonApiModel>(modelType: ModelType<T>, params?: any, headers?: Headers): Observable<DocumentModel<T[]>> {
let options: RequestOptions = this.getOptions(headers);
let url: string = this.buildUrl(modelType, params);
return this.http.get(url, options)
.map((res: any) => this.extractQueryData(res, modelType))
.catch((res: any) => this.handleError(res));
}

findRecord<T extends JsonApiModel>(modelType: ModelType<T>, id: string, params?: any, headers?: Headers): Observable<T> {
findRecord<T extends JsonApiModel>(modelType: ModelType<T>, id: string, params?: any, headers?: Headers): Observable<DocumentModel<T>> {
let options: RequestOptions = this.getOptions(headers);
let url: string = this.buildUrl(modelType, params, id);
return this.http.get(url, options)
Expand All @@ -40,7 +46,7 @@ export class JsonApiDatastore {
return new modelType(this, {attributes: data});
}

saveRecord<T extends JsonApiModel>(attributesMetadata: any, model?: T, params?: any, headers?: Headers): Observable<T> {
saveRecord<T extends JsonApiModel>(attributesMetadata: any, model?: T, params?: any, headers?: Headers): Observable<DocumentModel<T>> {
let modelType = <ModelType<T>>model.constructor;
let typeName: string = Reflect.getMetadata('JsonApiModelConfig', modelType).type;
let options: RequestOptions = this.getOptions(headers);
Expand Down Expand Up @@ -123,9 +129,10 @@ export class JsonApiDatastore {
return relationships;
}

private extractQueryData<T extends JsonApiModel>(res: any, modelType: ModelType<T>): T[] {
private extractQueryData<T extends JsonApiModel>(res: any, modelType: ModelType<T>): DocumentModel<T[]> {
let body: any = res.json();
let models: T[] = [];
let document: DocumentModel<T[]> = new DocumentModel<T[]>(body);
body.data.forEach((data: any) => {
let model: T = new modelType(this, data);
this.addToStore(model);
Expand All @@ -135,11 +142,13 @@ export class JsonApiDatastore {
}
models.push(model);
});
return models;
document.data = models;
return document;
}

private extractRecordData<T extends JsonApiModel>(res: any, modelType: ModelType<T>, model?: T): T {
private extractRecordData<T extends JsonApiModel>(res: any, modelType: ModelType<T>, model?: T): DocumentModel<T> {
let body: any = res.json();
let document: DocumentModel<T> = new DocumentModel<T>(body);
if (model) {
model.id = body.data.id;
_.extend(model, body.data.attributes);
Expand All @@ -150,7 +159,8 @@ export class JsonApiDatastore {
model.syncRelationships(body.data, body.included, 0);
this.addToStore(model);
}
return model;
document.data = model;
return document;
}

protected handleError(error: any): ErrorObservable {
Expand Down