Update src/app/services/crudServices/crud.service.ts
This commit is contained in:
parent
9fec45a91f
commit
fd32ae5dcc
@ -178,3 +178,165 @@ export class CombinedKeyCrudService<T> implements ICrudService<T> {
|
||||
}
|
||||
|
||||
}
|
||||
// Type definitions
|
||||
type TextResponse = { message: string };
|
||||
/**
|
||||
* Base CRUD service that targets the provided controller path.
|
||||
*
|
||||
* It mirrors the endpoints of CrudBaseApiController<T>:
|
||||
* GET /api/{controller}
|
||||
* GET /api/{controller}/{id}
|
||||
* POST /api/{controller} -> string
|
||||
* POST /api/{controller}/batch -> string[]
|
||||
* PUT /api/{controller}
|
||||
* PUT /api/{controller}/batch -> number
|
||||
* DELETE /api/{controller}/{id}
|
||||
* DELETE /api/{controller}/batch -> text summary
|
||||
* GET /api/{controller}/{id}/exists -> boolean
|
||||
* GET /api/{controller}/count -> number
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CrudBaseApiService<T extends object> {
|
||||
/**
|
||||
* Example: baseUrl = 'https://your-api', controller = 'Customer' →
|
||||
* endpoint = 'https://your-api/api/Customer'
|
||||
*/
|
||||
protected readonly endpoint: string;
|
||||
|
||||
|
||||
/**
|
||||
* @param http Angular HttpClient
|
||||
* @param baseUrl API root without trailing slash (e.g., environment.apiBaseUrl)
|
||||
* @param controllerName Controller name (e.g., 'Customer', 'Orders')
|
||||
*/
|
||||
constructor(
|
||||
protected http: HttpClient,
|
||||
protected apiConfig: ApiConfigService,
|
||||
@Inject(String) private controllerName: string
|
||||
) {
|
||||
this.endpoint = apiConfig.getApiUrl(this.controllerName);
|
||||
}
|
||||
|
||||
|
||||
/** Optional default headers (JSON). Override in subclasses if needed. */
|
||||
protected get jsonHeaders(): HttpHeaders {
|
||||
return new HttpHeaders({ 'Content-Type': 'application/json' });
|
||||
}
|
||||
|
||||
|
||||
/** Shared error handler that surfaces useful messages. */
|
||||
protected handleError(error: HttpErrorResponse): Observable<never> {
|
||||
let msg = 'Unknown error';
|
||||
if (error.error instanceof Blob) {
|
||||
// In case backend returns text/plain; charset=utf-8 as Blob
|
||||
return throwError(() => new Error('Server returned an error blob'));
|
||||
}
|
||||
if (typeof error.error === 'string') msg = error.error;
|
||||
else if (error.error?.message) msg = error.error.message;
|
||||
else if (error.message) msg = error.message;
|
||||
return throwError(() => new Error(msg));
|
||||
}
|
||||
/** Prepare the response for the given entity. Override in subclasses if needed. */
|
||||
protected prepareResponse(response: T): T {
|
||||
// Do nothing by default
|
||||
return response;
|
||||
}
|
||||
|
||||
/** GET /api/{controller} */
|
||||
getAll(): Observable<T[]> {
|
||||
return this.http
|
||||
.get<T[]>(this.endpoint)
|
||||
.pipe(
|
||||
map(response => {
|
||||
|
||||
for (let i = 0; i < response.length; i++) {
|
||||
const element = response[i];
|
||||
response[i] = this.prepareResponse(element);
|
||||
}
|
||||
return response;
|
||||
}),
|
||||
catchError(err => this.handleError(err)));
|
||||
}
|
||||
|
||||
|
||||
/** GET /api/{controller}/{id} */
|
||||
getById(id: string): Observable<T> {
|
||||
return this.http
|
||||
.get<T>(`${this.endpoint}/${id}`)
|
||||
.pipe(
|
||||
map(response => this.prepareResponse(response)),
|
||||
catchError(err => this.handleError(err)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** POST /api/{controller} -> string */
|
||||
create(entity: T): Observable<string> {
|
||||
return this.http
|
||||
.post<string>(this.endpoint, entity, { headers: this.jsonHeaders })
|
||||
.pipe(catchError(err => this.handleError(err)));
|
||||
}
|
||||
|
||||
|
||||
/** POST /api/{controller}/batch -> string[] */
|
||||
createRange(entities: T[]): Observable<string[]> {
|
||||
return this.http
|
||||
.post<string[]>(`${this.endpoint}/batch`, entities, { headers: this.jsonHeaders })
|
||||
.pipe(catchError(err => this.handleError(err)));
|
||||
}
|
||||
|
||||
|
||||
/** PUT /api/{controller} */
|
||||
update(entity: T): Observable<void> {
|
||||
return this.http
|
||||
.put<void>(this.endpoint, entity, { headers: this.jsonHeaders })
|
||||
.pipe(catchError(err => this.handleError(err)));
|
||||
}
|
||||
|
||||
|
||||
/** PUT /api/{controller}/batch -> number (updated count) */
|
||||
updateRange(entities: T[]): Observable<number> {
|
||||
return this.http
|
||||
.put<number>(`${this.endpoint}/batch`, entities, { headers: this.jsonHeaders })
|
||||
.pipe(catchError(err => this.handleError(err)));
|
||||
}
|
||||
|
||||
|
||||
/** DELETE /api/{controller}/{id} */
|
||||
delete(id: string): Observable<void> {
|
||||
return this.http
|
||||
.delete<void>(`${this.endpoint}/${id}`)
|
||||
.pipe(catchError(err => this.handleError(err)));
|
||||
}
|
||||
|
||||
|
||||
/** DELETE /api/{controller}/batch -> text summary */
|
||||
deleteRange(ids: string[]): Observable<TextResponse> {
|
||||
// API returns a plain text message; map it into a TextResponse for convenience
|
||||
return this.http
|
||||
.delete(`${this.endpoint}/batch`, {
|
||||
body: ids,
|
||||
headers: this.jsonHeaders
|
||||
})
|
||||
.pipe(
|
||||
map((response: any) => ({ message: response || 'Batch delete completed' })),
|
||||
catchError(err => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/** GET /api/{controller}/{id}/exists -> boolean */
|
||||
exists(id: string): Observable<boolean> {
|
||||
return this.http
|
||||
.get<boolean>(`${this.endpoint}/${id}/exists`)
|
||||
.pipe(catchError(err => this.handleError(err)));
|
||||
}
|
||||
|
||||
|
||||
/** GET /api/{controller}/count -> number */
|
||||
count(): Observable<number> {
|
||||
return this.http
|
||||
.get<number>(`${this.endpoint}/count`)
|
||||
.pipe(catchError(err => this.handleError(err)));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user