-
Notifications
You must be signed in to change notification settings - Fork 25
Open
Description
Hi,
is it worth adding turning new angular resource api into AsyncData<Result,exn> type?
export function toAsyncDataResult<T>(
ref: ResourceRef<T | null | undefined>,
): AsyncData<Result<Option<T>, string>> {
switch (ref.status()) {
case "idle":
return AsyncData.NotAsked();
case "loading":
return AsyncData.Loading();
case "reloading":
case "local": {
// Keep showing previous data during reload
const value = ref.value();
return isNil(value)
? AsyncData.Loading() // fallback if no previous data
: AsyncData.Done(Result.Ok(Option.Some(value)));
}
case "error": {
const error = ref.error()?.message ?? "Unknown error";
return AsyncData.Done(Result.Error(error));
}
case "resolved": {
const value = ref.value();
return isNil(value)
? AsyncData.Done(Result.Ok(Option.None()))
: AsyncData.Done(Result.Ok(Option.Some(value)));
}
}
}Also defining resource is nice with result type ->
export const DateSchema = z.string().refine(
(val) => {
const date = new Date(val);
return Number.isFinite(date.getTime());
},
{
message: "Invalid Date parameter",
},
);
export const validate = <T>(
schema: z.ZodType<T>,
value: unknown,
): Result<T, string> => {
const result = schema.safeParse(value);
return result.success
? Result.Ok(result.data)
: Result.Error(z.prettifyError(result.error));
};
post = resource({
params: () => ({ id: this.id(), createdAt: this.createdAt() }),
loader: ({ params }) => {
const id = validate(IdSchema, params.id);
const date = validate(DateSchema, params.createdAt);
const parameters = Result.all([id, date]);
return parameters.match({
Ok: ([id, date]) => firstValueFrom(queryPost(this.client, id, date)),
Error: (error) => {
this.snackbar.open(error, "Close", {
duration: 5000,
});
throw new Error("Invalid parameters");
},
});
},
});
I think it fits quite well even with angular for people used to functional way of thinking.
Metadata
Metadata
Assignees
Labels
No labels