Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: add additional params get hooks and post hook #40

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
7 changes: 7 additions & 0 deletions src/hooks/interfaces/useGetParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface UseGetParams<T> {
apiActionHandler: T;
id: string;
includes?: string[];
headers?: { [key: string]: string };
additionalUrlParam?: string;
}
18 changes: 16 additions & 2 deletions src/hooks/useGet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { RootState } from "../interfaces/RootState";
import { RequestMethod } from "../selectors/enums/RequestMethod";
import { StateHelper } from "../services/StateHelper/StateHelper";
import { ExtractJSONAModel } from "../types/UtilityTypes";
import { ApiThunkAction } from "../json-api-client/interfaces/ApiThunkAction";

export const useGet = <
T extends ApiActionHandler<JSONAModel>,
Expand All @@ -16,15 +17,28 @@ export const useGet = <
id: string,
includes?: string[],
headers?: { [key: string]: string },
additionalUrlParam?: string,
): {
operation: Operation;
record: F | null;
loading: boolean;
} => {
const dispatch = useDispatch();
let action: ApiThunkAction | undefined = undefined;
if (additionalUrlParam) {
action = apiActionHandler.get(
id,
includes,
headers,
additionalUrlParam,
);
} else {
action = apiActionHandler.get(id, includes, headers);
}

useEffect(() => {
dispatch(apiActionHandler.get(id, includes, headers));
}, [apiActionHandler, id, includes, dispatch, headers]);
dispatch(action);
}, [action, dispatch, headers]);

const operation = apiActionHandler.operationUtility.getOperationGet(id);
const loading = useSelector((state: RootState) => {
Expand Down
13 changes: 11 additions & 2 deletions src/hooks/useGetAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const useGetAll = <
apiActionHandler: T,
jsonApiQuery?: JsonApiQuery,
headers?: { [key: string]: string },
additionalUrlParam?: string,
): {
operation: Operation;
ids: string[];
Expand All @@ -25,9 +26,17 @@ export const useGetAll = <
count: number | undefined;
} => {
const dispatch = useDispatch();
let action = apiActionHandler.getAll(jsonApiQuery, headers);
if (additionalUrlParam) {
action = apiActionHandler.getAll(
jsonApiQuery,
headers,
additionalUrlParam,
);
}
useEffect(() => {
dispatch(apiActionHandler.getAll(jsonApiQuery, headers));
}, [apiActionHandler, jsonApiQuery, dispatch, headers]);
dispatch(action);
}, [apiActionHandler, jsonApiQuery, dispatch, action]);

const operation = apiActionHandler.operationUtility.getOperationGetAll(
jsonApiQuery,
Expand Down
13 changes: 11 additions & 2 deletions src/hooks/useGetAllControlled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const useGetAllControlled = <
apiActionHandler: T,
jsonApiQuery?: JsonApiQuery,
headers?: { [key: string]: string },
additionalUrlParam?: string,
): {
operation: Operation;
ids: string[];
Expand All @@ -30,15 +31,23 @@ export const useGetAllControlled = <
const dispatch: Dispatch = useDispatch();
const getAll = useCallback(() => {
return new Promise<JsonApiObject[]>((resolve, reject) => {
dispatch(apiActionHandler.getAll(jsonApiQuery, headers))
let action = apiActionHandler.getAll(jsonApiQuery, headers);
if (additionalUrlParam) {
action = apiActionHandler.getAll(
jsonApiQuery,
headers,
additionalUrlParam,
);
}
dispatch(action)
.then((response) => {
resolve(response?.data as JsonApiObject[]);
})
.catch((e) => {
reject(e);
});
});
}, [apiActionHandler, dispatch, jsonApiQuery, headers]);
}, [apiActionHandler, dispatch, jsonApiQuery, additionalUrlParam, headers]);

const operation = apiActionHandler.operationUtility.getOperationGetAll(
jsonApiQuery,
Expand Down
13 changes: 12 additions & 1 deletion src/hooks/useGetControlled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const useGetControlled = <
id: string,
includes?: string[],
headers?: { [key: string]: string },
additionalUrlParam?: string,
): {
operation: Operation;
record: F;
Expand All @@ -27,7 +28,17 @@ export const useGetControlled = <
const dispatch: Dispatch = useDispatch();
const getSingle = useCallback(() => {
return new Promise<JsonApiObject>((resolve, reject) => {
dispatch(apiActionHandler.get(id, includes, headers))
let action = apiActionHandler.get(id, includes, headers);
if (additionalUrlParam) {
action = apiActionHandler.get(
id,
includes,
headers,
additionalUrlParam,
);
}

dispatch(action)
.then((response) => {
resolve(response?.data as JsonApiObject);
})
Expand Down
11 changes: 10 additions & 1 deletion src/hooks/usePost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const usePost = <
>(
apiActionHandler: T,
headers?: { [key: string]: string },
additionalUrlParam?: string,
): {
operation: Operation;
record: F | null;
Expand All @@ -29,7 +30,15 @@ export const usePost = <
const create = useCallback(
(data: ActionPostData) => {
return new Promise<JsonApiObject>((resolve, reject) => {
dispatch(apiActionHandler.create(data, headers))
let action = apiActionHandler.create(data, headers);
if (additionalUrlParam) {
action = apiActionHandler.create(
data,
headers,
additionalUrlParam,
);
}
dispatch(action)
.then((response) => {
setId((response?.data as JsonApiObject)?.id || "");
resolve(response?.data as JsonApiObject);
Expand Down
18 changes: 16 additions & 2 deletions src/json-api-client/ApiActionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export class ApiActionHandler<T extends JSONAModel> {
public create(
data: ActionPostData,
headers?: { [key: string]: string },
additionalUrlParam?: string,
): ApiThunkAction {
const method = RequestMethod.Post;
const operation = new ApiOperation({
Expand All @@ -95,8 +96,13 @@ export class ApiActionHandler<T extends JSONAModel> {
{ model, includeNames },
);

let endpoint = this.endpoint;
if (additionalUrlParam) {
endpoint = this.endpoint + additionalUrlParam;
}

return ApiActionCreator.createAction({
endpoint: this.endpoint,
endpoint,
operation,
method,
requestConfig: { data: serializedData },
Expand All @@ -107,6 +113,7 @@ export class ApiActionHandler<T extends JSONAModel> {
public getAll(
jsonApiQuery?: JsonApiQuery,
headers?: { [key: string]: string },
additionalUrlParam?: string,
): ApiThunkAction {
const method = RequestMethod.Get;
const operation = new ApiOperation({
Expand All @@ -115,8 +122,13 @@ export class ApiActionHandler<T extends JSONAModel> {
jsonApiQuery,
});

let endpoint = this.endpoint;
if (additionalUrlParam) {
endpoint = this.endpoint + additionalUrlParam;
}

const config = {
endpoint: this.endpoint,
endpoint,
operation,
method: RequestMethod.Get,
requestConfig:
Expand All @@ -131,6 +143,7 @@ export class ApiActionHandler<T extends JSONAModel> {
id: string,
includes: string[] = [],
headers?: { [key: string]: string },
additionalUrlParam?: string,
): ApiThunkAction {
const jsonApiQuery = new JsonApiQuery({ includes });
const method = RequestMethod.Get;
Expand All @@ -146,6 +159,7 @@ export class ApiActionHandler<T extends JSONAModel> {
operation,
method,
requestConfig: jsonApiQuery.getRequestConfig(headers),
additionalUrlParam,
preserveRequestTrailingSlash: this.preserveRequestTrailingSlash,
});
}
Expand Down
53 changes: 37 additions & 16 deletions src/services/ApiActionCreator/ApiActionCreator.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { AxiosError } from "axios";
import { CreateApiActionConfigParam } from "./interfaces/CreateApiActionConfigParam";
import { ApiActionType } from "./enums/ApiActionType";
import { ApiReduxAction } from "./interfaces/ApiReduxAction";
import { Endpoint } from "../../interfaces/Endpoint";
import { Dispatch } from "../../interfaces/Dispatch";
import { ApiOperation } from "../../json-api-client/ApiOperation/ApiOperation";
import { ApiStatusTypePrefix } from "./enums/ApiStatusTypePrefix";
import { ActionStatus } from "./enums/ActionStatus";
import { RequestMethod } from "../../selectors/enums/RequestMethod";
import { ApiResponse } from "./interfaces/ResponseData";
import { FetchFromApiSuccessAction } from "./interfaces/FetchFromApiSuccessAction";
import { ActionStatus } from "./enums/ActionStatus";
import { ApiActionType } from "./enums/ApiActionType";
import { ApiStatusTypePrefix } from "./enums/ApiStatusTypePrefix";
import { ApiReduxAction } from "./interfaces/ApiReduxAction";
import { CreateApiActionConfigParam } from "./interfaces/CreateApiActionConfigParam";
import { FetchFromApiFailedAction } from "./interfaces/FetchFromApiFailedAction";
import { Dispatch } from "../../interfaces/Dispatch";
import { Endpoint } from "../../interfaces/Endpoint";
import { FetchFromApiSuccessAction } from "./interfaces/FetchFromApiSuccessAction";
import { ApiResponse } from "./interfaces/ResponseData";

export class ApiActionCreator {
public static createAction(config: CreateApiActionConfigParam) {
Expand Down Expand Up @@ -69,6 +69,7 @@ export class ApiActionCreator {
reject = () => {
return;
},
additionalUrlParam,
apiActionType = ApiActionType.JsonApiRequest,
preserveRequestTrailingSlash,
}: CreateApiActionConfigParam): ApiReduxAction {
Expand All @@ -80,11 +81,12 @@ export class ApiActionCreator {
operationValue = id ? `${operation}_${id}` : operation;
}

const formattedEndpoint = ApiActionCreator.createEndpoint(
const formattedEndpoint = ApiActionCreator.createEndpoint({
endpoint,
id,
additionalUrlParam,
preserveRequestTrailingSlash,
);
});

return {
// todo: maybe simplify this to not include whole query?
Expand Down Expand Up @@ -137,18 +139,37 @@ export class ApiActionCreator {
};
}

private static createEndpoint(
endpoint: Endpoint,
id?: string,
preserveRequestTrailingSlash?: boolean,
): string {
private static createEndpoint({
endpoint,
id,
additionalUrlParam,
preserveRequestTrailingSlash,
}: {
endpoint: Endpoint;
id?: string;
additionalUrlParam?: string;
preserveRequestTrailingSlash?: boolean;
}): string {
const trailingSlashEndpoint =
endpoint.substr(-1) === "/" ? endpoint : `${endpoint}/`;

if (
id !== undefined &&
id !== "" &&
additionalUrlParam !== undefined &&
additionalUrlParam !== ""
) {
return `${trailingSlashEndpoint}${id}${additionalUrlParam}`;
}

if (id !== undefined && id !== "") {
return `${trailingSlashEndpoint}${id}`;
}

if (additionalUrlParam !== undefined && additionalUrlParam !== "") {
return `${trailingSlashEndpoint}${additionalUrlParam}`;
}

if (preserveRequestTrailingSlash) {
return trailingSlashEndpoint;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";
import { Endpoint } from "../../../interfaces/Endpoint";
import { Operation } from "../../../interfaces/Operation";
import { ApiOperation } from "../../../json-api-client/ApiOperation/ApiOperation";
import { Endpoint } from "../../../interfaces/Endpoint";
import { RequestMethod } from "../../../selectors/enums/RequestMethod";
import { ApiActionType } from "../enums/ApiActionType";

Expand All @@ -12,6 +12,7 @@ export interface CreateApiActionConfigParam {
method?: RequestMethod;
requestConfig?: AxiosRequestConfig;
apiActionType?: ApiActionType;
additionalUrlParam?: string;
preserveRequestTrailingSlash?: boolean;

resolve?: (responseData: AxiosResponse) => void;
Expand Down
Loading