Implementing Pagination with Effect and RequestResolver in Nuxt
class NoPostsError extends Error {
readonly _tag = "NoPostsError";
constructor() {
super("All of posts are already displayed?!");
}
}
interface FetchPosts extends Request.Request<PostsCollectionItem[], Error> {
readonly _tag: "FetchPosts";
readonly page: number;
readonly pageSize: number;
}
const FetchPosts = Request.tagged<FetchPosts>("FetchPosts");
const FetchPostsResolver = RequestResolver.fromEffect(
(request: FetchPosts): Effect.Effect<PostsCollectionItem[], Error> => {
const skip = (request.page - 1) * request.pageSize;
const limit = request.pageSize;
return Effect.tryPromise({
try: async () => {
return await queryCollection("posts")
.limit(limit)
.skip(skip)
.all();
},
catch: (error) =>
new Error(`Error fetching posts: ${String(error)}`),
});
},
);
const fetchPostsEffect = (
page: number,
pageSize: number,
): Effect.Effect<PostsCollectionItem[], Error> => {
return pipe(
Effect.request(FetchPosts({ page, pageSize }), FetchPostsResolver),
Effect.flatMap((posts) =>
posts?.length > 0
? Effect.succeed(posts)
: Effect.fail(new NoPostsError()),
),
);
};
//Pagination stuff
const currentPage = ref(1);
const postsPerPage = 2;
const {
data: posts,
error,
refresh,
} = await useAsyncData(
"posts-page",
async () =>
await Effect.runPromise(
fetchPostsEffect(currentPage.value, postsPerPage),
),
);
const nextPage = () => {
if (posts.value && posts.value.length >= postsPerPage) {
currentPage.value++;
}
};
const prevPage = () => {
if (currentPage.value > 1) {
currentPage.value--;
}
};
watch(currentPage, () => refresh());class NoPostsError extends Error {
readonly _tag = "NoPostsError";
constructor() {
super("All of posts are already displayed?!");
}
}
interface FetchPosts extends Request.Request<PostsCollectionItem[], Error> {
readonly _tag: "FetchPosts";
readonly page: number;
readonly pageSize: number;
}
const FetchPosts = Request.tagged<FetchPosts>("FetchPosts");
const FetchPostsResolver = RequestResolver.fromEffect(
(request: FetchPosts): Effect.Effect<PostsCollectionItem[], Error> => {
const skip = (request.page - 1) * request.pageSize;
const limit = request.pageSize;
return Effect.tryPromise({
try: async () => {
return await queryCollection("posts")
.limit(limit)
.skip(skip)
.all();
},
catch: (error) =>
new Error(`Error fetching posts: ${String(error)}`),
});
},
);
const fetchPostsEffect = (
page: number,
pageSize: number,
): Effect.Effect<PostsCollectionItem[], Error> => {
return pipe(
Effect.request(FetchPosts({ page, pageSize }), FetchPostsResolver),
Effect.flatMap((posts) =>
posts?.length > 0
? Effect.succeed(posts)
: Effect.fail(new NoPostsError()),
),
);
};
//Pagination stuff
const currentPage = ref(1);
const postsPerPage = 2;
const {
data: posts,
error,
refresh,
} = await useAsyncData(
"posts-page",
async () =>
await Effect.runPromise(
fetchPostsEffect(currentPage.value, postsPerPage),
),
);
const nextPage = () => {
if (posts.value && posts.value.length >= postsPerPage) {
currentPage.value++;
}
};
const prevPage = () => {
if (currentPage.value > 1) {
currentPage.value--;
}
};
watch(currentPage, () => refresh());is this a good approach to follow on nuxt?
