I'm using the urql GraphQL-Client to run a bunch of queries in a component. I want to create a loading
computed prop indicating if any of these queries are running. To be able to easily compute this, I wrapped the queries in an object:
const gql = {
queryA: doQueryA(),
queryB: doQueryB(),
queryC: doQueryC()
};
which should allow me to compute the loading state like:
// does not work
const loading = computed(() => Object.values(gql).some(query => query.fetching));
however, this does not update once all queries are done. Doing it explicitly works:
// works
const loading = computed(() =>
gql.queryA.fetching ||
gql.queryB.fetching ||
gql.queryC.fetching
);
which made me think that since .some
can return early, maybe that's a problem for Vues reactivity tracking. So I tried to force it to access every query every time:
// does not work
const loading = computed(() => Object.values(gql)
.map(query => query.fetching)
.some(isFetching => isFetching));
However, that does not help either.
Can somebody explain why this problem exists?
Urql's .fetching
is a ref<boolean>
. That means that the code needs to be adjusted to
const loading = computed(() => Object.values(gql)
.map(query => query.fetching)
.some(isFetching => isFetching.value)); // add .value access
otherwise the reference that is isFetching
will always be truthy.
Then how did the other example work? Well, it all comes down to the fact that "" || 7
is not true
but 7
. So ref(false) || ref(true)
will just be ref(false)
. Effectively, my loading
property was just tracking the first of all the queries, which gave the impression that it was at least doing something. Not the right thing, though.