Skip to content

Instantly share code, notes, and snippets.

@lukaspili
Last active October 13, 2022 19:28
Show Gist options
  • Save lukaspili/46412bb57cbde915fab0fa69fb083a4d to your computer and use it in GitHub Desktop.
Save lukaspili/46412bb57cbde915fab0fa69fb083a4d to your computer and use it in GitHub Desktop.
const fetcher = async ({ path, method = "get", query, body }: FetcherPayload) => {
let url = `${process.env.NEXT_PUBLIC_API_URL}/${path}`;
if (query != undefined) {
url += `?${new URLSearchParams(query)}`;
}
console.log(`[api] ${method} ${url}`);
const token = Cookies.get("token");
let response: Response;
try {
response = await fetch(url, {
headers: {
"Content-type": "application/json; charset=UTF-8",
...(token != undefined ? { Authorization: `Token token=${token}` } : {}),
},
method: method.toUpperCase(),
body: JSON.stringify(Recase.snakeCopy(body)),
mode: "cors",
credentials: "include",
});
} catch (e) {
console.error("[api] http failed: ", e);
return Result.failure();
}
if (response.status == 401) {
await sessionManager.signOut();
}
let data = null;
try {
data = await response.json();
} catch (e) {
return response.status === 200 ? Result.successful() : Result.failure();
}
data = Recase.camelCopy(data);
if (data.error != null) {
const message: string | undefined =
(data.error.messages?.length ?? 0) > 0 ? data.error.messages.join(", ") : undefined;
return Result.failure(message);
} else {
return Result.successful(data.data, data.meta);
}
};
export enum Status {
Idle = "idle",
Loading = "loading",
Succeeded = "succeeded",
Failed = "failed",
}
export class Task {
status: Status;
result?: Result;
private constructor(status: Status, result?: Result) {
this.status = status;
this.result = result;
}
static idle(): Task {
return new Task(Status.Idle);
}
static loading(): Task {
return new Task(Status.Loading);
}
static succeeded(result?: Result): Task {
return new Task(Status.Succeeded, result);
}
static failed(result: Result): Task {
return new Task(Status.Failed, result);
}
static fromResult(result: Result): Task {
return new Task(result.successful ? Status.Succeeded : Status.Failed, result);
}
get isLoading() {
return this.status == Status.Loading;
}
get hasSucceeded() {
return this.status == Status.Succeeded;
}
get hasFailed() {
return this.status == Status.Failed;
}
}
export class Result {
successful: boolean;
data?: any;
message?: string;
meta?: any;
private constructor(successful: boolean, data?: any, message?: string, meta?: any) {
this.successful = successful;
this.data = data;
this.message = message;
this.meta = meta;
}
static successful(data?: any, meta?: any): Result {
return new Result(true, data, undefined, meta);
}
static failure(message?: string): Result {
return new Result(false, undefined, message ?? "Failed");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment