Skip to content

Commit

Permalink
Merge pull request #70 from FinnStutzenstein/actionResponse
Browse files Browse the repository at this point in the history
Get action results
  • Loading branch information
FinnStutzenstein committed Nov 12, 2020
2 parents 2b8a0c6 + 7d05f00 commit ff4d233
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 68 deletions.
61 changes: 53 additions & 8 deletions client/src/app/core/core-services/action.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,30 @@ import { Injectable } from '@angular/core';

import { HttpService } from './http.service';

export interface RequestInfo {
export interface ActionRequest {
action: string;
data: any;
data: any[];
}

interface ActionResponse<T extends {}> {
success: true;
message: string;
results?: ((T | null)[] | null)[];
}
function isActionResponse<T extends {}>(obj: any): obj is ActionResponse<T> {
const response = obj as ActionResponse<T>;
return !!obj && response.success === true && !!response.message;
}

interface ActionError {
success: false;
message: string;
error_index?: number;
}

function isActionError(obj: any): obj is ActionError {
const response = obj as ActionError;
return !!obj && response.success === false && !!response.message;
}

@Injectable({
Expand All @@ -15,15 +36,39 @@ export class ActionService {

private constructor(private http: HttpService) {}

public async sendRequest<T>(action: string, data: any): Promise<T> {
return this._sendRequest({ action, data: [data] });
public async sendRequest<T>(action: string, data: any): Promise<T | null> {
const results = await this._sendRequest<T>({ action, data: [data] });
if (!results) {
return null;
}
if (results.length !== 1) {
throw new Error('Inner resultlength is not 1 from the action service');
}
return results[0];
}

public async sendBulkRequest<T>(action: string, data: any[]): Promise<T> {
return this._sendRequest({ action, data });
public async sendBulkRequest<T>(action: string, data: any[]): Promise<T[] | null> {
const results = await this._sendRequest<T>({ action, data });
if (results.length !== data.length) {
throw new Error(`Inner resultlength is not ${data.length} from the action service`);
}
return results;
}

private async _sendRequest<T>(request: RequestInfo): Promise<T> {
return await this.http.post<T>(this.ACTION_URL, [request]);
private async _sendRequest<T>(request: ActionRequest): Promise<T[] | null> {
const response = await this.http.post<T>(this.ACTION_URL, [request]);
if (isActionError(response)) {
throw response.message;
} else if (isActionResponse<T>(response)) {
const results = response.results;
if (!results) {
return null;
}
if (results.length !== 1) {
throw new Error('Resultlength is not 1 from the action service');
}
return results[0];
}
throw new Error('Unknown return type from action service');
}
}
56 changes: 4 additions & 52 deletions client/src/app/core/core-services/http.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,7 @@ import { HttpOptions } from '../definitions/http-options';
import { formatQueryParams, QueryParams } from '../definitions/query-params';
import { toBase64 } from '../to-base64';

export interface ErrorDetailResponse {
detail: string | string[];
args?: string[];
}

function isErrorDetailResponse(obj: any): obj is ErrorDetailResponse {
return (
obj &&
typeof obj === 'object' &&
(typeof obj.detail === 'string' || obj.detail instanceof Array) &&
(!obj.args || obj.args instanceof Array)
);
}

export interface ErrorMessageResponse {
interface ErrorMessageResponse {
message: string;
success: boolean;
}
Expand Down Expand Up @@ -142,27 +128,16 @@ export class HttpService {
return error;
}

if (e.status === 405) {
// this should only happen, if the url is wrong -> a bug.
error += this.translate.instant(
'The requested method is not allowed. Please contact your system administrator.'
);
} else if (!e.error) {
if (!e.error) {
error += this.translate.instant("The server didn't respond.");
} else if (typeof e.error === 'object') {
if (isErrorDetailResponse(e.error)) {
error += this.processErrorDetailResponse(e.error);
} else if (isErrorMessageResponse(e.error)) {
if (isErrorMessageResponse(e.error)) {
error += e.error.message;
} else {
const errorList = Object.keys(e.error).map(key => {
const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
const message = e.error[key];
if (typeof message === 'string') {
return `${this.translate.instant(capitalizedKey)}: ${message}`;
} else {
return `${this.translate.instant(capitalizedKey)}: ${this.processErrorDetailResponse(message)}`;
}
return `${this.translate.instant(capitalizedKey)}: ${message}`;
});
error = errorList.join(', ');
}
Expand All @@ -179,29 +154,6 @@ export class HttpService {
return error;
}

/**
* Errors from the servers may be string or array of strings. This function joins the strings together,
* if an array is send.
* @param str a string or a string array to join together.
* @returns Error text(s) as single string
*/
private processErrorDetailResponse(response: ErrorDetailResponse): string {
let message: string;
if (response.detail instanceof Array) {
message = response.detail.join(' ');
} else {
message = response.detail;
}
message = this.translate.instant(message);

if (response.args && response.args.length > 0) {
for (let i = 0; i < response.args.length; i++) {
message = message.replace(`{${i}}`, response.args[i].toString());
}
}
return message;
}

/**
* Executes a get on a path with a certain object
* @param path The path to send the request to.
Expand Down
18 changes: 14 additions & 4 deletions client/src/app/core/repositories/base-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,11 +340,21 @@ export abstract class BaseRepository<V extends BaseViewModel, M extends BaseMode
this.repositoryServiceCollector.errorService.showError(errorMessage);
};

protected sendActionToBackend(action: string, payload: any): Promise<any> {
return this.actions.sendRequest(action, payload).catch(this.raiseError);
protected async sendActionToBackend(action: string, payload: any): Promise<any> {
try {
return await this.actions.sendRequest(action, payload);
} catch (e) {
this.raiseError(e);
throw e;
}
}

protected sendBulkActionToBackend(action: string, payload: any[]): Promise<any> {
return this.actions.sendBulkRequest(action, payload).catch(this.raiseError);
protected async sendBulkActionToBackend(action: string, payload: any[]): Promise<any> {
try {
return await this.actions.sendBulkRequest(action, payload);
} catch (e) {
this.raiseError(e);
throw e;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -515,10 +515,8 @@ export class AssignmentDetailComponent extends BaseModelContextComponent impleme
*/
public async createAssignment(): Promise<void> {
try {
/*const response = */ await this.assignmentRepo.create(this.assignmentForm.value);
console.error('TODO: wait for returned id and navigate to it');
this.router.navigate([`./assignments/`]);
// this.router.navigate([`./assignments/${response.id}`]);
const response = await this.assignmentRepo.create(this.assignmentForm.value);
this.router.navigate([`./assignments/${response.id}`]);
} catch (e) {
this.raiseError(e);
}
Expand Down

0 comments on commit ff4d233

Please sign in to comment.