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