Nooby
Nooby2w ago

Dealing with images

Hi, do you think, it's the good way to deal with images :
import { v } from "convex/values";
import { query } from "./_generated/server";
import { paginationOptsValidator } from "convex/server";
import { R2 } from "@convex-dev/r2";
import { components } from "./_generated/api";

const r2 = new R2(components.r2);

export const listProductsWithImages = query({
args: { paginationOpts: paginationOptsValidator },
handler: async (ctx, args) => {
// Paginate products
const results = await ctx.db
.query("products")
.paginate(args.paginationOpts);

// For each product in the page, fetch image URLs and sizes
const page = await Promise.all(
results.page.map(async (product) => {
const imageUrls = await Promise.all(
(product.imageKeys ?? []).map((key) => r2.getUrl(key))
);
const imageSizes = await Promise.all(
(product.imageKeys ?? []).map(async (key) => {
return await ctx.db
.query("imageSizes")
.withIndex("by_image_key", (q) => q.eq("imageKey", key))
.first();
})
);
return {
...product,
imageUrls,
imageSizes,
};
})
);

// Return the paginated result, replacing the page with the enriched data
return {
...results,
page,
};
},
});
import { v } from "convex/values";
import { query } from "./_generated/server";
import { paginationOptsValidator } from "convex/server";
import { R2 } from "@convex-dev/r2";
import { components } from "./_generated/api";

const r2 = new R2(components.r2);

export const listProductsWithImages = query({
args: { paginationOpts: paginationOptsValidator },
handler: async (ctx, args) => {
// Paginate products
const results = await ctx.db
.query("products")
.paginate(args.paginationOpts);

// For each product in the page, fetch image URLs and sizes
const page = await Promise.all(
results.page.map(async (product) => {
const imageUrls = await Promise.all(
(product.imageKeys ?? []).map((key) => r2.getUrl(key))
);
const imageSizes = await Promise.all(
(product.imageKeys ?? []).map(async (key) => {
return await ctx.db
.query("imageSizes")
.withIndex("by_image_key", (q) => q.eq("imageKey", key))
.first();
})
);
return {
...product,
imageUrls,
imageSizes,
};
})
);

// Return the paginated result, replacing the page with the enriched data
return {
...results,
page,
};
},
});
4 Replies
Convex Bot
Convex Bot2w ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
Nooby
NoobyOP2w ago
@kapa.ai Ingestor answer
erquhart
erquhart2w ago
You can make a post in #ask-ai to talk to kapa Yep, this code is fine. convex-helpers includes a lot of helpful stuff, one if asyncMap, which can shorten some of this
const imageUrls = await asyncMap(
product.imageKeys ?? [],
(key) => r2.getUrl(key)
);
const imageUrls = await asyncMap(
product.imageKeys ?? [],
(key) => r2.getUrl(key)
);
Nooby
NoobyOP2w ago
Thanks for the help

Did you find this page helpful?