Async query scopes

Hi there!

I’m quite new to AdonisJS but loving it so far… I’m having a bit of an issue, and I suspect I already know the answer, but I just want to confirm: a query scope can not be async, can it?

Say I need to grab ids from another table in my scope function, that’s an async call that needs to happen in order for me to correctly build the scope’s query… But when I try to do that, I get the “Make sure to call fetch to execute the query” error…

Thanks for any hint/help!

Most probably you need to end your call chain with .fetch():

The fetch method is required to to execute the query ensuring results return within a serializer instance


1 Like

Thanks, yes but you wouldn’t call .fetch() within the scope function, would you? So if the scope function is async, it seems to trigger a check in the query builder that issues that error when .then() is called before .fetch()… I am thinking this may be a bug, almost as if the check to make sure .fetch() is called is too “global”…

For now, I’ve taken the route of subqueries so I don’t have to make the scope function async…

Every database query needs async-await method

const product = await Product.query()
			.where("product_id", product_id)
			.with("user", builder =>['id', 'name'])

Fetch is part of Query Builder, maybe you got confused with Lucid ORM that doesn’t need .fetch()

Thanks for the reply - but I do understand the fetching and async mechanism. I’m saying, though, that you can’t have an async scope method, i.e. this will not work:

class User { ... static async scopeFriendsOfVisitor (query, visitor) { const user_ids = await Friendships.query().where("user_id","friend_id") return query.whereIn("id", user_ids) } ... }
Because the scope is async, in effect, the call chain will be something like:

User.scopeFriendsOfVisitor(query, visitor).then(...)
And that trips up the .fetch() warning… I think Lucid’s warning did not consider that particular use case which, I believe, is totally valid… In that particular scenario, we are calling .then() before .fetch() but not because we forgot to call .fetch()… It’ll just be called later down the chain.