sanity icon indicating copy to clipboard operation
sanity copied to clipboard

The use of the refetch with GROQ param refs since GROQ does not support conditional params

Open toddpadwick opened this issue 3 years ago • 1 comments

I have a blog listing page which has the following params:

  • $industrySlug which is used as an optional filter, whereby if applied it filters blog articles by a reference field. so && industry->slug.current == $industry
  • $offset - which is used to calculate pagination

I might be missing something, but currently, according to this line of the docs, the sanity fetch module listens to changes to the computed properties past into the params argument to trigger a refetch. However, after speaking with the Sanity team in Slack to confirm, GROQ does not support conditional params. Meaning if a param is empty, I'll end up with [_type in ["article"] && industry->slug.current == null, which will return no articles instead of all articles. What I of course need is [_type in ["article]] if no industry is passed. As GROQ does not support conditionals params, any conditional logic has to be handled before the GROQ string is concatenated and passed into the query, however, the module won't be listening to those changes.

const blogQuery = `*[_type == "article"${industry ? ' && industry->slug.current == ${industrySlug}' : ''}]`; // contains conditional logic if industry exists

If there was a way to manually refetch, this might suffice, but if there is a way to listen for changes to the query string that would probably be best otherwise we're doubling up on watchers.

toddpadwick avatar Dec 01 '22 11:12 toddpadwick

Updating you on a failed attempted workaround: tried using the refetch hook, however, it doesn't regenerate the query string, so the issue still remains:

<script setup>
  import querySrc from '~/queries/groq/entries';

  const limit = ref(12);

  const config = useRuntimeConfig();
  const route = useRoute();

  let options = {types:props.types, limit:limit.value}; // setting base options

  const page = route.params?.page ? parseInt(route.params.page) : 1;
  console.log(page);
  if (page && page > 1) {
    options.offset = limit.value * (page - 1);
  }
  if (route.query.industry) { // listening for filters applied to the route query
    options.industry = route.query.industry;
  }

  if (route.query.role) { // listening for filters applied to the route.query
    options.role = route.query.role;
  }

  const entriesQuery = querySrc(options); // setting the options in my GROQ query concatonation.

  const {pending, data:entries, error, refresh} = useSanityQuery(entriesQuery);


  watch(route, () => {

    refresh(); // This refreshes the previous entriesQuery, not the updated one with new params.
    
  });

</script>

toddpadwick avatar Dec 02 '22 18:12 toddpadwick