diff --git a/projects/openharbor/ngx-data/package.json b/projects/openharbor/ngx-data/package.json index ac5d62f..a5095b5 100644 --- a/projects/openharbor/ngx-data/package.json +++ b/projects/openharbor/ngx-data/package.json @@ -1,12 +1,12 @@ { "name": "@openharbor/ngx-data", - "version": "0.1.0", + "version": "18.0.0-alpha.1", "dependencies": { - "tslib": "^2.0.0" + "tslib": "^2.7.0" }, "peerDependencies": { - "@angular/common": "^8.2.4", - "@angular/core": "^8.2.4", + "@angular/common": "^18.0.0", + "@angular/core": "^18.0.0", "@poweredsoft/data": "^0.0.31", "rxjs": "^6.5.3" } diff --git a/projects/openharbor/ngx-data/src/lib/BaseHttpDataSourceOptionsBuilder.ts b/projects/openharbor/ngx-data/src/lib/BaseHttpDataSourceOptionsBuilder.ts index 8f82c8c..81a6b56 100644 --- a/projects/openharbor/ngx-data/src/lib/BaseHttpDataSourceOptionsBuilder.ts +++ b/projects/openharbor/ngx-data/src/lib/BaseHttpDataSourceOptionsBuilder.ts @@ -1,128 +1,138 @@ -import { HttpClient, HttpErrorResponse } from "@angular/common/http"; -import { DataSource, IDataSource, IDataSourceCommandAdapterOptions, IDataSourceError, IDataSourceErrorMessage, IDataSourceOptions, IDataSourceQueryAdapterOptions, IDataSourceTransportOptions, IDataSourceValidationError, IQueryCriteria, IResolveCommandModelEvent } from "@poweredsoft/data"; -import { Observable, of, throwError } from "rxjs"; -import { catchError, switchMap } from "rxjs/operators"; - - +import {HttpClient, HttpErrorResponse} from "@angular/common/http"; +import { + DataSource, + IDataSource, + IDataSourceCommandAdapterOptions, + IDataSourceError, + IDataSourceErrorMessage, + IDataSourceOptions, + IDataSourceQueryAdapterOptions, + IDataSourceTransportOptions, + IDataSourceValidationError, + IQueryCriteria, + IResolveCommandModelEvent +} from "@poweredsoft/data"; +import {Observable, of, throwError} from "rxjs"; +import {catchError, switchMap} from "rxjs/operators"; export abstract class BaseHttpDataSourceOptionsBuilder { - protected _commands: { [key: string]: IDataSourceCommandAdapterOptions; } = {}; - protected _keyResolver: (model: TModel) => TKey; - protected _defaultCriteria: IQueryCriteria; - protected _query: IDataSourceQueryAdapterOptions; + protected _commands: { [key: string]: IDataSourceCommandAdapterOptions; } = {}; + protected _keyResolver: (model: TModel) => TKey; + protected _defaultCriteria: IQueryCriteria; + protected _query: IDataSourceQueryAdapterOptions; - constructor(protected http: HttpClient) { - } + constructor(protected http: HttpClient) { + } - createDataSource(): IDataSource { - return new DataSource(this.createOptions()); - } + createDataSource(): IDataSource { + return new DataSource(this.createOptions()); + } - protected createTransport(): IDataSourceTransportOptions { - let ret: IDataSourceTransportOptions = { - query: this._query, - commands: this._commands - }; - return ret; - } + protected createTransport(): IDataSourceTransportOptions { + let ret: IDataSourceTransportOptions = { + query: this._query, + commands: this._commands + }; + return ret; + } - public keyResolver(resolver: (model: TModel) => TKey) { - this._keyResolver = resolver; - return this; - } + public keyResolver(resolver: (model: TModel) => TKey) { + this._keyResolver = resolver; + return this; + } - createOptions(): IDataSourceOptions { - let ret: IDataSourceOptions = { - resolveIdField: this._keyResolver, - defaultCriteria: this._defaultCriteria, - transport: this.createTransport() - }; - return ret; - } + createOptions(): IDataSourceOptions { + let ret: IDataSourceOptions = { + resolveIdField: this._keyResolver, + defaultCriteria: this._defaultCriteria, + transport: this.createTransport() + }; + return ret; + } - private _messageErrorHandler(err: HttpErrorResponse) { - - if (typeof err.error == "object") { - // if status not okay then its an exception error - if (err.error.hasOwnProperty('Message') && typeof (err.error['Message']) == "string") { - return throwError({ - type: 'message', - message: err.error['Message'] - }); - } - else if (err.error.hasOwnProperty('message') && typeof (err.error['message']) == "string") { - return throwError({ - type: 'message', - message: err.error['message'] - }); - } - } - - // general error message - if (typeof (err.error) == "string") { - return throwError({ - type: 'message', - message: err.error - }); - } + private _messageErrorHandler(err: HttpErrorResponse) { + if (typeof err.error == "object") { + // if status not okay then its an exception error + if (err.error.hasOwnProperty('Message') && typeof (err.error['Message']) == "string") { return throwError({ - type: 'message', - message: 'UNEXPECTED_ERROR_MESSAGE' + type: 'message', + message: err.error['Message'] + }); + } + else if (err.error.hasOwnProperty('message') && typeof (err.error['message']) == "string") { + return throwError({ + type: 'message', + message: err.error['message'] + }); + } + } + + // general error message + if (typeof (err.error) == "string") { + return throwError({ + type: 'message', + message: err.error + }); + } + + return throwError({ + type: 'message', + message: 'UNEXPECTED_ERROR_MESSAGE' + }); + } + + private _handleErrorPipe(err: HttpErrorResponse): Observable { + + if (err.status == 400) { + if (err.error && err.error.errors) + return throwError({ + type: 'validation', + errors: err.error.errors }); } - private _handleErrorPipe(err: HttpErrorResponse): Observable { - - if (err.status == 400) { - if (err.error && err.error.errors) - return throwError({ - type: 'validation', - errors: err.error.errors - }); - } - - return this._messageErrorHandler(err); - } + return this._messageErrorHandler(err); + } - public addCommandByCallback(name: string, commandHandler: (command: TCommand) => Observable, resolveCommandModel?: (event: IResolveCommandModelEvent) => Observable) { - const handleWrapper = command => { - return commandHandler(command).pipe(catchError(this._handleErrorPipe.bind(this))); - }; + public addCommandByCallback(name: string, commandHandler: (command: TCommand) => Observable, resolveCommandModel?: (event: IResolveCommandModelEvent) => Observable) { + const handleWrapper = command => { + return commandHandler(command).pipe(catchError(this._handleErrorPipe.bind(this))); + }; - this._commands[name] = >{ - adapter: { - handle: handleWrapper - }, - resolveCommandModel: resolveCommandModel - }; + this._commands[name] = >{ + adapter: { + handle: handleWrapper + }, + resolveCommandModel: resolveCommandModel + }; - return this; - } + return this; + } - public addCommandByUrl(name: string, url: string, resolveCommandModel?: (event: IResolveCommandModelEvent) => Observable, beforeCommand?: (command: TCommand) => Observable) { - const handleWrapper = command => { - const finalBeforeCommand = beforeCommand || (_ => of(command)); - return finalBeforeCommand(command) - .pipe( - switchMap(finalCommand => { - return this.http.post(url, finalCommand).pipe(catchError(this._handleErrorPipe.bind(this))); - }) - ); - }; + public addCommandByUrl(name: string, url: string, resolveCommandModel?: (event: IResolveCommandModelEvent) => Observable, beforeCommand?: (command: TCommand) => Observable) { + const handleWrapper = command => { + const finalBeforeCommand = beforeCommand || (_ => of(command)); + return finalBeforeCommand(command) + .pipe( + switchMap(finalCommand => { + return this.http.post(url, finalCommand).pipe(catchError(this._handleErrorPipe.bind(this))); + }) + ); + }; - this._commands[name] = >{ - adapter: { - handle: handleWrapper - }, - resolveCommandModel: resolveCommandModel - }; + this._commands[name] = >{ + adapter: { + handle: handleWrapper + }, + resolveCommandModel: resolveCommandModel + }; - return this; - } + return this; + } } diff --git a/projects/openharbor/ngx-data/src/lib/HttpDataSourceBuilder.ts b/projects/openharbor/ngx-data/src/lib/HttpDataSourceBuilder.ts index 69a6dc4..ac90c32 100644 --- a/projects/openharbor/ngx-data/src/lib/HttpDataSourceBuilder.ts +++ b/projects/openharbor/ngx-data/src/lib/HttpDataSourceBuilder.ts @@ -1,62 +1,60 @@ -import { HttpClient, HttpResponse } from "@angular/common/http"; -import { IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult } from "@poweredsoft/data"; -import { Observable, of } from "rxjs"; -import { switchMap } from "rxjs/operators"; -import { BaseHttpDataSourceOptionsBuilder } from "./BaseHttpDataSourceOptionsBuilder"; +import {HttpClient} from "@angular/common/http"; +import {IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult} from "@poweredsoft/data"; +import {Observable, of} from "rxjs"; +import {switchMap} from "rxjs/operators"; +import {BaseHttpDataSourceOptionsBuilder} from "./BaseHttpDataSourceOptionsBuilder"; -export class HttpDataSourceOptionsBuilder - extends BaseHttpDataSourceOptionsBuilder +export class HttpDataSourceOptionsBuilder extends BaseHttpDataSourceOptionsBuilder { - private _beforeRead: (TQuery: IQueryCriteria) => Observable; + private _beforeRead: (TQuery: IQueryCriteria) => Observable; + constructor(http: HttpClient) { + super(http); + } - constructor(http: HttpClient) { - super(http); - } + public beforeRead(beforeRead: (query: TDynamicQuery) => Observable) { + this._beforeRead = beforeRead; + return this; + } - public beforeRead(beforeRead: (query: TDynamicQuery) => Observable) { - this._beforeRead = beforeRead; - return this; - } - - public queryUrl(url: string) { - this._query = { - adapter: { - handle: (query: IQueryCriteria) => { - const finalBeforeRead = this._beforeRead || (t => of(query)); - return finalBeforeRead(query) - .pipe( - switchMap(finalQuery => { - return this.http.post & IQueryExecutionGroupResult>(url, finalQuery); - }) - ); - } - } + public queryUrl(url: string) { + this._query = { + adapter: { + handle: (query: IQueryCriteria) => { + const finalBeforeRead = this._beforeRead || (t => of(query)); + return finalBeforeRead(query) + .pipe( + switchMap(finalQuery => { + return this.http.post & IQueryExecutionGroupResult>(url, finalQuery); + }) + ); } - - return this; + } } - public queryHandler(queryHandler: (query: TQuery) => Observable & IQueryExecutionGroupResult>) { - this._query = { - adapter: { - handle: (query: TQuery) => { - const finalBeforeRead = this._beforeRead || (t => of(query)); - return finalBeforeRead(query) - .pipe( - switchMap(finalQuery => { - return queryHandler(finalQuery as any); - }) - ); - } - } + return this; + } + + public queryHandler(queryHandler: (query: TQuery) => Observable & IQueryExecutionGroupResult>) { + this._query = { + adapter: { + handle: (query: TQuery) => { + const finalBeforeRead = this._beforeRead || (t => of(query)); + return finalBeforeRead(query) + .pipe( + switchMap(finalQuery => { + return queryHandler(finalQuery as any); + }) + ); } - - return this; + } } - defaultCriteria(criteria: IQueryCriteria) { - this._defaultCriteria = criteria; - return this; - } + return this; + } + + defaultCriteria(criteria: IQueryCriteria) { + this._defaultCriteria = criteria; + return this; + } } diff --git a/projects/openharbor/ngx-data/src/lib/ListDataSourceBuilder.ts b/projects/openharbor/ngx-data/src/lib/ListDataSourceBuilder.ts index dba17c5..cdad906 100644 --- a/projects/openharbor/ngx-data/src/lib/ListDataSourceBuilder.ts +++ b/projects/openharbor/ngx-data/src/lib/ListDataSourceBuilder.ts @@ -1,107 +1,107 @@ -import { HttpClient } from "@angular/common/http"; -import { IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult, IQueryExecutionResultPaging } from "@poweredsoft/data"; -import { Observable, of } from "rxjs"; -import { map, switchMap } from "rxjs/operators"; -import { BaseHttpDataSourceOptionsBuilder } from "./BaseHttpDataSourceOptionsBuilder"; +import {HttpClient} from "@angular/common/http"; +import {IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult} from "@poweredsoft/data"; +import {Observable, of} from "rxjs"; +import {map, switchMap} from "rxjs/operators"; +import {BaseHttpDataSourceOptionsBuilder} from "./BaseHttpDataSourceOptionsBuilder"; -export class ListDataSourceOptionsBuilder - extends BaseHttpDataSourceOptionsBuilder +export class ListDataSourceOptionsBuilder + extends BaseHttpDataSourceOptionsBuilder { - private _beforeRead: (query: IQueryCriteria) => Observable; - - constructor(http: HttpClient) { - super(http); - } + private _beforeRead: (query: IQueryCriteria) => Observable; - public beforeRead(beforeRead: (query: IQueryCriteria) => Observable) { - this._beforeRead = beforeRead; - return this; - } + constructor(http: HttpClient) { + super(http); + } - public queryUrlWithGet(url: string) { - this._query = { - adapter: { - handle: (query: IQueryCriteria) => { - const finalBeforeRead = this._beforeRead || ((_: IQueryCriteria) => of({})); - return finalBeforeRead(query) - .pipe( - switchMap(finalQuery => { - return this.http.get(url, { - params: this.convertToParams(finalQuery) - }).pipe( - map(result => { - return & IQueryExecutionGroupResult> - { - totalRecords: result.length, - data: result - }; - }) - ) - }) - ); - } - } + public beforeRead(beforeRead: (query: IQueryCriteria) => Observable) { + this._beforeRead = beforeRead; + return this; + } + + public queryUrlWithGet(url: string) { + this._query = { + adapter: { + handle: (query: IQueryCriteria) => { + const finalBeforeRead = this._beforeRead || ((_: IQueryCriteria) => of({})); + return finalBeforeRead(query) + .pipe( + switchMap(finalQuery => { + return this.http.get(url, { + params: this.convertToParams(finalQuery) + }).pipe( + map(result => { + return & IQueryExecutionGroupResult> + { + totalRecords: result.length, + data: result + }; + }) + ) + }) + ); } - - return this; + } } - protected convertToParams(finalQuery: TQuery) - { - return Object.keys(finalQuery).reduce((prev, key) => { - prev[key] = finalQuery[key]; - return prev; - }, {} as { [param: string]: string | string[]; }); - } + return this; + } - public queryUrl(url: string) { - this._query = { - adapter: { - handle: (query: IQueryCriteria) => { - const finalBeforeRead = this._beforeRead || ((_: IQueryCriteria) => of({})); - return finalBeforeRead(query) - .pipe( - switchMap(finalQuery => { - return this.http.post(url, finalQuery).pipe( - map(result => { - return & IQueryExecutionGroupResult> - { - totalRecords: result.length, - data: result - }; - }) - ) - }) - ); - } - } + protected convertToParams(finalQuery: TQuery) + { + return Object.keys(finalQuery).reduce((prev, key) => { + prev[key] = finalQuery[key]; + return prev; + }, {} as { [param: string]: string | string[]; }); + } + + public queryUrl(url: string) { + this._query = { + adapter: { + handle: (query: IQueryCriteria) => { + const finalBeforeRead = this._beforeRead || ((_: IQueryCriteria) => of({})); + return finalBeforeRead(query) + .pipe( + switchMap(finalQuery => { + return this.http.post(url, finalQuery).pipe( + map(result => { + return & IQueryExecutionGroupResult> + { + totalRecords: result.length, + data: result + }; + }) + ) + }) + ); } - - return this; + } } - public queryHandler(queryHandler: (query: IQueryCriteria) => Observable) { - this._query = { - adapter: { - handle: (query: TQuery) => { - const finalBeforeRead = this._beforeRead || (t => of({})); - return finalBeforeRead(query) - .pipe( - switchMap(finalQuery => { - return queryHandler(finalQuery).pipe( - map(result => { - return & IQueryExecutionGroupResult>{ - totalRecords: result.length, - data: result - }; - }) - ) - }) - ); - } - } + return this; + } + + public queryHandler(queryHandler: (query: IQueryCriteria) => Observable) { + this._query = { + adapter: { + handle: (query: TQuery) => { + const finalBeforeRead = this._beforeRead || (t => of({})); + return finalBeforeRead(query) + .pipe( + switchMap(finalQuery => { + return queryHandler(finalQuery).pipe( + map(result => { + return & IQueryExecutionGroupResult>{ + totalRecords: result.length, + data: result + }; + }) + ) + }) + ); } - - return this; + } } + + return this; + } } diff --git a/projects/openharbor/ngx-data/src/lib/SingleObjectDataSourceBuilder.ts b/projects/openharbor/ngx-data/src/lib/SingleObjectDataSourceBuilder.ts index 1aaafd8..d001197 100644 --- a/projects/openharbor/ngx-data/src/lib/SingleObjectDataSourceBuilder.ts +++ b/projects/openharbor/ngx-data/src/lib/SingleObjectDataSourceBuilder.ts @@ -1,103 +1,103 @@ -import { HttpClient } from '@angular/common/http'; -import { IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult, IQueryExecutionResultPaging } from '@poweredsoft/data'; -import { Observable, of } from 'rxjs'; -import { map, switchMap } from 'rxjs/operators'; -import { BaseHttpDataSourceOptionsBuilder } from './BaseHttpDataSourceOptionsBuilder'; +import {HttpClient} from '@angular/common/http'; +import {IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult} from '@poweredsoft/data'; +import {Observable, of} from 'rxjs'; +import {map, switchMap} from 'rxjs/operators'; +import {BaseHttpDataSourceOptionsBuilder} from './BaseHttpDataSourceOptionsBuilder'; export class SingleDataSourceOptionsBuilder - extends BaseHttpDataSourceOptionsBuilder { - private _beforeRead: (query: IQueryCriteria) => Observable; + extends BaseHttpDataSourceOptionsBuilder { + private _beforeRead: (query: IQueryCriteria) => Observable; - constructor(http: HttpClient) { - super(http); - } + constructor(http: HttpClient) { + super(http); + } - public beforeRead(beforeRead: (query: IQueryCriteria) => Observable) { - this._beforeRead = beforeRead; - return this; - } + public beforeRead(beforeRead: (query: IQueryCriteria) => Observable) { + this._beforeRead = beforeRead; + return this; + } - public queryUrlWithGet(url: string) { - this._query = { - adapter: { - handle: (query: IQueryCriteria) => { - const finalBeforeRead = this._beforeRead || ((query: IQueryCriteria) => of({} as TQuery)); - return finalBeforeRead(query) - .pipe( - switchMap(finalQuery => { - return this.http.get(url, { - params: this.convertToParams(finalQuery) - }).pipe( - map(result => { - return { - totalRecords: result == null ? 0 : 1, - data: [result] - } as IQueryExecutionResult & IQueryExecutionGroupResult; - }) - ); - }) - ); - } - } - }; + public queryUrlWithGet(url: string) { + this._query = { + adapter: { + handle: (query: IQueryCriteria) => { + const finalBeforeRead = this._beforeRead || ((query: IQueryCriteria) => of({} as TQuery)); + return finalBeforeRead(query) + .pipe( + switchMap(finalQuery => { + return this.http.get(url, { + params: this.convertToParams(finalQuery) + }).pipe( + map(result => { + return { + totalRecords: result == null ? 0 : 1, + data: [result] + } as IQueryExecutionResult & IQueryExecutionGroupResult; + }) + ); + }) + ); + } + } + }; - return this; - } + return this; + } - protected convertToParams(finalQuery: TQuery) { - return Object.keys(finalQuery).reduce((prev, key) => { - prev[key] = finalQuery[key]; - return prev; - }, {} as { [param: string]: string | string[]; }); - } + protected convertToParams(finalQuery: TQuery) { + return Object.keys(finalQuery).reduce((prev, key) => { + prev[key] = finalQuery[key]; + return prev; + }, {} as { [param: string]: string | string[]; }); + } - public queryUrl(url: string) { - this._query = { - adapter: { - handle: (query: IQueryCriteria) => { - const finalBeforeRead = this._beforeRead || ((_: IQueryCriteria) => of({} as TQuery)); - return finalBeforeRead(query) - .pipe( - switchMap(finalQuery => { - return this.http.post(url, finalQuery).pipe( - map(result => { - return { - totalRecords: result == null ? 0 : 1, - data: [result] - } as IQueryExecutionResult & IQueryExecutionGroupResult; - }) - ); - }) - ); - } - } - }; + public queryUrl(url: string) { + this._query = { + adapter: { + handle: (query: IQueryCriteria) => { + const finalBeforeRead = this._beforeRead || ((_: IQueryCriteria) => of({} as TQuery)); + return finalBeforeRead(query) + .pipe( + switchMap(finalQuery => { + return this.http.post(url, finalQuery).pipe( + map(result => { + return { + totalRecords: result == null ? 0 : 1, + data: [result] + } as IQueryExecutionResult & IQueryExecutionGroupResult; + }) + ); + }) + ); + } + } + }; - return this; - } + return this; + } - public queryHandler(queryHandler: (query: IQueryCriteria) => Observable) { - this._query = { - adapter: { - handle: (query: TQuery) => { - const finalBeforeRead = this._beforeRead || (t => of({})); - return finalBeforeRead(query) - .pipe( - switchMap(finalQuery => { - return queryHandler(finalQuery).pipe( - map(result => { - return { - totalRecords: result == null ? 0 : 1, - data: [result] - } as IQueryExecutionResult & IQueryExecutionGroupResult; - }) - ); - }) - ); - } - } - }; + public queryHandler(queryHandler: (query: IQueryCriteria) => Observable) { + this._query = { + adapter: { + handle: (query: TQuery) => { + const finalBeforeRead = this._beforeRead || (t => of({})); + return finalBeforeRead(query) + .pipe( + switchMap(finalQuery => { + return queryHandler(finalQuery).pipe( + map(result => { + return { + totalRecords: result == null ? 0 : 1, + data: [result] + } as IQueryExecutionResult & IQueryExecutionGroupResult; + }) + ); + }) + ); + } + } + }; - return this; - } + return this; + } } diff --git a/projects/openharbor/ngx-data/src/lib/http-data-source-service.service.ts b/projects/openharbor/ngx-data/src/lib/http-data-source-service.service.ts index 25d33aa..ea4cfbf 100644 --- a/projects/openharbor/ngx-data/src/lib/http-data-source-service.service.ts +++ b/projects/openharbor/ngx-data/src/lib/http-data-source-service.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from "@angular/core"; +import {Inject, Injectable} from "@angular/core"; import { HttpClient } from '@angular/common/http'; import { HttpDataSourceOptionsBuilder } from "./HttpDataSourceBuilder"; import { SingleDataSourceOptionsBuilder } from "./SingleObjectDataSourceBuilder"; @@ -6,21 +6,20 @@ import { ListDataSourceOptionsBuilder } from "./ListDataSourceBuilder"; @Injectable({ - providedIn: 'root' + providedIn: 'root' }) export class HttpDataSourceService { - constructor(private http: HttpClient) { - } + @Inject(HttpClient) protected http!: HttpClient; - builder() { - return new HttpDataSourceOptionsBuilder(this.http); - } + builder() { + return new HttpDataSourceOptionsBuilder(this.http); + } - singleBuilder() { - return new SingleDataSourceOptionsBuilder(this.http); - } + singleBuilder() { + return new SingleDataSourceOptionsBuilder(this.http); + } - listBuilder() { - return new ListDataSourceOptionsBuilder(this.http); - } + listBuilder() { + return new ListDataSourceOptionsBuilder(this.http); + } } diff --git a/projects/openharbor/ngx-data/src/lib/ngx-data.module.ts b/projects/openharbor/ngx-data/src/lib/ngx-data.module.ts deleted file mode 100644 index 97c572d..0000000 --- a/projects/openharbor/ngx-data/src/lib/ngx-data.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { NgModule } from '@angular/core'; - - - -@NgModule({ - declarations: [], - imports: [ - ], - exports: [], -}) -export class NgxDataModule { } diff --git a/projects/openharbor/ngx-data/src/lib/ngx-data.service.ts b/projects/openharbor/ngx-data/src/lib/ngx-data.service.ts index 5949323..54fc02d 100644 --- a/projects/openharbor/ngx-data/src/lib/ngx-data.service.ts +++ b/projects/openharbor/ngx-data/src/lib/ngx-data.service.ts @@ -1,130 +1,151 @@ -import { Injectable } from '@angular/core'; -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { IDataSourceTransportOptions, IDataSourceCommandAdapterOptions, IDataSourceOptions, IResolveCommandModelEvent, IDataSourceError, IDataSourceErrorMessage, IDataSourceValidationError } from '@poweredsoft/data'; -import { IQueryExecutionResult, IQueryExecutionGroupResult, IQueryCriteria } from '@poweredsoft/data'; -import { IDataSourceQueryAdapterOptions } from '@poweredsoft/data'; -import { catchError, switchMap} from 'rxjs/operators'; -import { throwError, Observable, of } from 'rxjs'; +import {Inject, Injectable} from '@angular/core'; +import {HttpClient, HttpErrorResponse} from '@angular/common/http'; +import { + IDataSourceCommandAdapterOptions, + IDataSourceError, + IDataSourceErrorMessage, + IDataSourceOptions, + IDataSourceQueryAdapterOptions, + IDataSourceTransportOptions, + IDataSourceValidationError, + IQueryCriteria, + IQueryExecutionGroupResult, + IQueryExecutionResult, + IResolveCommandModelEvent +} from '@poweredsoft/data'; +import {catchError, switchMap} from 'rxjs/operators'; +import {Observable, of, throwError} from 'rxjs'; + +/** + * providedIn: "root" + * + * Automatic Injection: When you use providedIn: "root", Angular automatically + * provides the service in the root injector, making it a singleton and available + * throughout the application without needing any manual import in a module. + * + * Tree-shakable: This method is tree-shakable, meaning if the service is not + * used anywhere in the application, it can be removed during the build process, + * reducing the final bundle size. + * + * Convenience: It is simpler for the user, as they do not need to worry about + * importing the module for the service. They can just inject the service wherever + * they need it. + * + */ @Injectable({ - providedIn: 'root' + providedIn: 'root' }) export class GenericRestDataSourceService { - constructor(private http: HttpClient) { + @Inject(HttpClient) protected http!: HttpClient; + private _handleErrorPipe(err: HttpErrorResponse) : Observable { + if (err.status == 500) { + return throwError({ + type: 'message', + message: 'UNEXPECTED_ERROR_MESSAGE' + }); } - private _handleErrorPipe(err: HttpErrorResponse) : Observable { - - if (err.status == 500) { - return throwError({ - type: 'message', - message: 'UNEXPECTED_ERROR_MESSAGE' - }); - } - - if (err.status == 400) - { - if (err.error && err.error.errors) - return throwError({ - type: 'validation', - errors: err.error.errors - }); - - // if status not okay then its an exception error - if (err.error.hasOwnProperty('Message') && typeof(err.error['Message']) == "string") { - return throwError({ - type: 'message', - message: err.error['Message'] - }); - } - } - - // general error message - if (typeof(err.error) == "string") { - return throwError({ - type: 'message', - message: err.error - }); - } - - return throwError({ - type: 'message', - message: 'UNEXPECTED_ERROR_MESSAGE' - }); - } - - createDataSourceOptions(route: string, keyResolver: (model: TModel) => TKey, defaultCriteria: IQueryCriteria, beforeRead?: (query: IQueryCriteria) => Observable) : IDataSourceOptions + if (err.status == 400) { - const dataSourceTransportOptions = this.createStandardRestTransportOptions(route, keyResolver, beforeRead); + if (err.error && err.error.errors) + return throwError({ + type: 'validation', + errors: err.error.errors + }); - const dataSourceOptions: IDataSourceOptions = { - defaultCriteria: defaultCriteria, - resolveIdField: keyResolver, - transport: dataSourceTransportOptions - }; - - return dataSourceOptions; + // if status not okay then it's an exception error + if (err.error.hasOwnProperty('Message') && typeof(err.error['Message']) == "string") { + return throwError({ + type: 'message', + message: err.error['Message'] + }); + } } - setResolveCommand(options: IDataSourceOptions, name: string, resolveCommandModel: (event: IResolveCommandModelEvent) => Observable) { - options.transport.commands[name].resolveCommandModel = resolveCommandModel; + // general error message + if (typeof(err.error) == "string") { + return throwError({ + type: 'message', + message: err.error + }); } - createStandardRestTransportOptions(route: string, keyResolver: (model: TModel) => TKey, beforeRead?: (query: IQueryCriteria) => Observable) : IDataSourceTransportOptions { + return throwError({ + type: 'message', + message: 'UNEXPECTED_ERROR_MESSAGE' + }); + } - const query: IDataSourceQueryAdapterOptions = { - adapter: { - handle: (criteria: IQueryCriteria) => { - const queryRoute = `${route}/read`; - const finalBeforeRead = beforeRead || (t => of(criteria)); - return finalBeforeRead(criteria) - .pipe( - switchMap(finalQuery => { - return this.http.post & IQueryExecutionGroupResult>(queryRoute, finalQuery); - }) - ); - } - } - }; + createDataSourceOptions(route: string, keyResolver: (model: TModel) => TKey, defaultCriteria: IQueryCriteria, beforeRead?: (query: IQueryCriteria) => Observable) : IDataSourceOptions + { + const dataSourceTransportOptions = this.createStandardRestTransportOptions(route, keyResolver, beforeRead); - const createCommand: IDataSourceCommandAdapterOptions = { - adapter: { - handle: (command: TModel) => { - return this.http.post(route, command).pipe(catchError(this._handleErrorPipe)); - } - } - }; + const dataSourceOptions: IDataSourceOptions = { + defaultCriteria: defaultCriteria, + resolveIdField: keyResolver, + transport: dataSourceTransportOptions + }; - const updateCommand: IDataSourceCommandAdapterOptions = { - adapter: { - handle: (command: TModel) => { - const key = keyResolver(command); - const updateRoute = `${route}/${encodeURIComponent(key as any)}`; - return this.http.put(updateRoute, command).pipe(catchError(this._handleErrorPipe)); - } - } - }; + return dataSourceOptions; + } - const deleteCommand: IDataSourceCommandAdapterOptions = { - adapter: { - handle: (command: TModel) => { - const key = keyResolver(command); - const updateRoute = `${route}/${encodeURIComponent(key as any)}`; - return this.http.delete(updateRoute).pipe(catchError(this._handleErrorPipe)); - } - } - }; + setResolveCommand(options: IDataSourceOptions, name: string, resolveCommandModel: (event: IResolveCommandModelEvent) => Observable) { + options.transport.commands[name].resolveCommandModel = resolveCommandModel; + } - return { - query: query, - commands: { - 'create': createCommand, - 'update': updateCommand, - 'delete': deleteCommand - } - }; - } + createStandardRestTransportOptions(route: string, keyResolver: (model: TModel) => TKey, beforeRead?: (query: IQueryCriteria) => Observable) : IDataSourceTransportOptions { + const query: IDataSourceQueryAdapterOptions = { + adapter: { + handle: (criteria: IQueryCriteria) => { + const queryRoute = `${route}/read`; + const finalBeforeRead = beforeRead || (t => of(criteria)); + return finalBeforeRead(criteria) + .pipe(switchMap(finalQuery => { + return this.http.post & IQueryExecutionGroupResult>(queryRoute, finalQuery); + })); + } + } + }; + + const createCommand: IDataSourceCommandAdapterOptions = { + adapter: { + handle: (command: TModel) => { + return this.http.post(route, command).pipe(catchError(this._handleErrorPipe)); + } + } + }; + + const updateCommand: IDataSourceCommandAdapterOptions = { + adapter: { + handle: (command: TModel) => { + const key = keyResolver(command); + const updateRoute = `${route}/${encodeURIComponent(key as any)}`; + return this.http.put(updateRoute, command).pipe(catchError(this._handleErrorPipe)); + } + } + }; + + const deleteCommand: IDataSourceCommandAdapterOptions = { + adapter: { + handle: (command: TModel) => { + const key = keyResolver(command); + const updateRoute = `${route}/${encodeURIComponent(key as any)}`; + return this.http.delete(updateRoute).pipe(catchError(this._handleErrorPipe)); + } + } + }; + + return { + query: query, + commands: { + 'create': createCommand, + 'update': updateCommand, + 'delete': deleteCommand + } + }; + } } diff --git a/projects/openharbor/ngx-data/src/public-api.ts b/projects/openharbor/ngx-data/src/public-api.ts index cf7c152..e41de91 100644 --- a/projects/openharbor/ngx-data/src/public-api.ts +++ b/projects/openharbor/ngx-data/src/public-api.ts @@ -1,7 +1,5 @@ /* * Public API Surface of ngx-data */ - export * from './lib/ngx-data.service'; export * from './lib/http-data-source-service.service' -export * from './lib/ngx-data.module';