hocino
hocino3w ago

custom functions and getAll helper

Hi everyone🙂 , I create two custom functions to handle my queries and mutations. Now, when I use the getAll helper as below I have some strange errors. Except that I can query or mutate everything with my customFunctions. Do you have any idea what is the problem ? Did I do something wrong with my custom Functions ? Thanks 🙏 GetAll : applicationsToUpdate = await getAll( ctx.db, childrenApplicationsIds.map((x) => x as Id<'applications'>) ); Here, thrown errors : Uncaught TypeError: Cannot read properties of undefined (reading 'reader') or Uncaught TypeError: Cannot read properties of undefined (reading 'db') My customs functions: export const SecureMutationBuilder = customMutation(mutation, { args: {}, input: async (ctx, args) => { const { userId, userPermissions } = await getPermissions(ctx); const db = wrapDatabaseWriter( { userId }, ctx.db, await rlsRules(ctx, userId, userPermissions) ); return { ctx: { db, userId, userPermissions }, args }; } }); export const SecureInternalMutationBuilder = customMutation(internalMutation, { args: {}, input: async (ctx, args) => { const { userId, userPermissions } = await getPermissions(ctx); const db = wrapDatabaseWriter( { userId }, ctx.db, await rlsRules(ctx, userId, userPermissions) ); return { ctx: { db, userId, userPermissions }, args }; } });
8 Replies
Convex Bot
Convex Bot3w 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!
lee
lee3w ago
Hmm looks like a bug in getAll. I wonder how long that has been there according to git, it has always been there 😮 as a workaround, instead of getAll(db, ids) you should asyncMap(ids, (id) => db.get(id))
hocino
hocinoOP3w ago
Ok thanks @lee for your help.
lee
lee3w ago
the bug fix is https://github.com/get-convex/convex-helpers/pull/366 if you're interested
GitHub
fix getAll to bind db by ldanilek · Pull Request #366 · get-convex/...
fixes getAll so it works with stateful db implementations, like WrapWriter as used by wrapDatabaseWriter for RLS. By submitting this pull request, I confirm that you can use, modify, copy, and re...
hocino
hocinoOP3w ago
Ok thanks. Could you just explain me what is the difference between WrapWriter db and the 'classic' db please ?
lee
lee3w ago
For the purposes of the getAll bug or in general? In general WrapWriter wraps functions like db.patch and checks your RLS rules before allowing the patch to go through For the purposes of the bug, WrapWriter has internal state like this.reader and this.rules. The "classic" db does not have internal state. When you write asyncMap(ids, db.get) in JavaScript, the db.get method will get called, but the value of this will be bogus. Doing (id) => db.get(id) fixes the problem
lee
lee3w ago
We could also do db.get.bind(db) (same effect, but less idiomatic). See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
MDN Web Docs
Function.prototype.bind() - JavaScript | MDN
The bind() method of Function instances creates a new function that, when called, calls this function with its this keyword set to the provided value, and a given sequence of arguments preceding any provided when the new function is called.
hocino
hocinoOP3w ago
thank you @lee for these explanations, the PR and the fix 🙂

Did you find this page helpful?