Skip to content
Merged
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
20 changes: 10 additions & 10 deletions src/models/json-api.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class JsonApiModel {
}
}

save(params?: any, headers?: Headers): Observable<JsonApiModel> {
save(params?: any, headers?: Headers): Observable<this> {
let attributesMetadata: any = Reflect.getMetadata('Attribute', this);
return this._datastore.saveRecord(attributesMetadata, this, params, headers);
}
Expand Down Expand Up @@ -69,7 +69,7 @@ export class JsonApiModel {
let relationship: any = data.relationships ? data.relationships[metadata.relationship]: null;
if (relationship && relationship.data && relationship.data.length > 0) {
let typeName: string = relationship.data[0].type;
let modelType: ModelType = Reflect.getMetadata('JsonApiDatastoreConfig', this._datastore.constructor).models[typeName];
let modelType: ModelType<this> = Reflect.getMetadata('JsonApiDatastoreConfig', this._datastore.constructor).models[typeName];
let relationshipModel: JsonApiModel[] = this.getHasManyRelationship(modelType, relationship.data, included, typeName, level);
if (relationshipModel.length > 0) {
this[metadata.propertyName] = relationshipModel;
Expand All @@ -88,7 +88,7 @@ export class JsonApiModel {
let dataRelationship: any = (relationship.data instanceof Array) ? relationship.data[0] : relationship.data;
if (dataRelationship) {
let typeName: string = dataRelationship.type;
let modelType: ModelType = Reflect.getMetadata('JsonApiDatastoreConfig', this._datastore.constructor).models[typeName];
let modelType: ModelType<this> = Reflect.getMetadata('JsonApiDatastoreConfig', this._datastore.constructor).models[typeName];
let relationshipModel: JsonApiModel = this.getBelongsToRelationship(modelType, dataRelationship, included, typeName, level);
if (relationshipModel) {
this[metadata.propertyName] = relationshipModel;
Expand All @@ -99,12 +99,12 @@ export class JsonApiModel {
}
}

private getHasManyRelationship(modelType: ModelType, data: any, included: any, typeName: string, level: number): JsonApiModel[] {
let relationshipList: JsonApiModel[] = [];
private getHasManyRelationship<T extends this>(modelType: ModelType<T>, data: any, included: any, typeName: string, level: number): T[] {
let relationshipList: T[] = [];
data.forEach((item: any) => {
let relationshipData: any = _.find(included, {id: item.id, type: typeName});
if (relationshipData) {
let newObject: JsonApiModel = this.createOrPeek(modelType, relationshipData);
let newObject: T = this.createOrPeek(modelType, relationshipData);
if (level <= 1) {
newObject.syncRelationships(relationshipData, included, level + 1);
}
Expand All @@ -115,11 +115,11 @@ export class JsonApiModel {
}


private getBelongsToRelationship(modelType: ModelType, data: any, included: any, typeName: string, level: number): JsonApiModel {
private getBelongsToRelationship<T extends this>(modelType: ModelType<T>, data: any, included: any, typeName: string, level: number): T {
let id: string = data.id;
let relationshipData: any = _.find(included, {id: id, type: typeName});
if (relationshipData) {
let newObject: JsonApiModel = this.createOrPeek(modelType, relationshipData);
let newObject: T = this.createOrPeek(modelType, relationshipData);
if (level <= 1) {
newObject.syncRelationships(relationshipData, included, level + 1);
}
Expand All @@ -128,12 +128,12 @@ export class JsonApiModel {
return this._datastore.peekRecord(modelType, id);
}

private createOrPeek(modelType: ModelType, data: any): JsonApiModel {
private createOrPeek<T extends this>(modelType: ModelType<T>, data: any): T {
let peek = this._datastore.peekRecord(modelType, data.id);
if (peek) {
return peek;
}
let newObject: JsonApiModel = new modelType(this._datastore, data);
let newObject: T = new modelType(this._datastore, data);
this._datastore.addToStore(newObject);
return newObject;
}
Expand Down
28 changes: 14 additions & 14 deletions src/services/json-api-datastore.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { JsonApiModel } from '../models/json-api.model';

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

@Injectable()
export class JsonApiDatastore {
Expand All @@ -19,28 +19,28 @@ export class JsonApiDatastore {
constructor(private http: Http) {
}

query(modelType: ModelType, params?: any, headers?: Headers): Observable<JsonApiModel[]> {
query<T extends JsonApiModel>(modelType: ModelType<T>, params?: any, headers?: Headers): Observable<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(modelType: ModelType, id: string, params?: any, headers?: Headers): Observable<JsonApiModel> {
findRecord<T extends JsonApiModel>(modelType: ModelType<T>, id: string, params?: any, headers?: Headers): Observable<T> {
let options: RequestOptions = this.getOptions(headers);
let url: string = this.buildUrl(modelType, params, id);
return this.http.get(url, options)
.map((res: any) => this.extractRecordData(res, modelType))
.catch((res: any) => this.handleError(res));
}

createRecord(modelType: ModelType, data?: any): JsonApiModel {
createRecord<T extends JsonApiModel>(modelType: ModelType<T>, data?: any): T {
return new modelType(this, {attributes: data});
}

saveRecord(attributesMetadata: any, model?: any, params?: any, headers?: Headers): Observable<JsonApiModel> {
let modelType = model.constructor;
saveRecord<T extends JsonApiModel>(attributesMetadata: any, model?: T, params?: any, headers?: Headers): Observable<T> {
let modelType = <ModelType<T>>model.constructor;
let typeName: string = Reflect.getMetadata('JsonApiModelConfig', modelType).type;
let options: RequestOptions = this.getOptions(headers);
let relationships: any = !model.id ? this.getRelationships(model) : undefined;
Expand Down Expand Up @@ -75,12 +75,12 @@ export class JsonApiDatastore {
.catch((res: any) => this.handleError(res));
}

peekRecord(modelType: ModelType, id: string): JsonApiModel {
peekRecord<T extends JsonApiModel>(modelType: ModelType<T>, id: string): T {
let type: string = Reflect.getMetadata('JsonApiModelConfig', modelType).type;
return this._store[type] ? this._store[type][id] : null;
}

peekAll(modelType: ModelType): JsonApiModel[] {
peekAll<T extends JsonApiModel>(modelType: ModelType<T>): T[] {
let type = Reflect.getMetadata('JsonApiModelConfig', modelType).type;
return _.values(<JsonApiModel>this._store[type]);
}
Expand All @@ -89,7 +89,7 @@ export class JsonApiDatastore {
this._headers = headers;
}

private buildUrl(modelType: ModelType, params?: any, id?: string): string {
private buildUrl<T extends JsonApiModel>(modelType: ModelType<T>, params?: any, id?: string): string {
let typeName: string = Reflect.getMetadata('JsonApiModelConfig', modelType).type;
let baseUrl: string = Reflect.getMetadata('JsonApiDatastoreConfig', this.constructor).baseUrl;
let idToken: string = id ? `/${id}` : null;
Expand All @@ -115,11 +115,11 @@ export class JsonApiDatastore {
return relationships;
}

private extractQueryData(res: any, modelType: ModelType): JsonApiModel[] {
private extractQueryData<T extends JsonApiModel>(res: any, modelType: ModelType<T>): T[] {
let body: any = res.json();
let models: JsonApiModel[] = [];
let models: T[] = [];
body.data.forEach((data: any) => {
let model: JsonApiModel = new modelType(this, data);
let model: T = new modelType(this, data);
this.addToStore(model);
if (body.included) {
model.syncRelationships(data, body.included, 0);
Expand All @@ -130,7 +130,7 @@ export class JsonApiDatastore {
return models;
}

private extractRecordData(res: any, modelType: ModelType, model?: JsonApiModel): JsonApiModel {
private extractRecordData<T extends JsonApiModel>(res: any, modelType: ModelType<T>, model?: T): T {
let body: any = res.json();
if (model) {
model.id = body.data.id;
Expand Down Expand Up @@ -208,7 +208,7 @@ export class JsonApiDatastore {
return _.keyBy(modelsArray, 'id');
}

private resetMetadataAttributes(res: any, attributesMetadata: any, modelType: ModelType) {
private resetMetadataAttributes<T extends JsonApiModel>(res: any, attributesMetadata: any, modelType: ModelType<T>) {
attributesMetadata = Reflect.getMetadata('Attribute', res);
for (let propertyName in attributesMetadata) {
if (attributesMetadata.hasOwnProperty(propertyName)) {
Expand Down