Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not reactive input data #539

Closed
ulysse-lacour opened this issue Aug 13, 2023 · 2 comments · Fixed by #597
Closed

Not reactive input data #539

ulysse-lacour opened this issue Aug 13, 2023 · 2 comments · Fixed by #597
Labels

Comments

@ulysse-lacour
Copy link

Environment

Operating System: Darwin

Describe the bug

I'm trying to create a search form (data in Strai backend, fetch via Graphql query) but using refresh method is using some sort of frozen query variable that is not updating, every request is send with variables to ''.

<script lang="ts" setup>
import { SEARCH_BLOGPOST_BY_TITLE } from "~/gql/SearchBlogPosts";
import type { BlogPostsType } from "~/types/BlogPosts";

const searchText = ref("");
const queryVariables = ref({
  Title: searchText.value,
});
const searchedData = ref<BlogPostsType>({ blogPosts: null });
let isLoading = ref(false);

const {
  data,
  error,
  refresh: search,
} = await useAsyncQuery<BlogPostsType>(
  SEARCH_BLOGPOST_BY_TITLE,
  queryVariables.value
);

const submitForm = async () => {
  isLoading.value = true;

  try {
    search();
  } catch (error) {
    console.log({ error });
  }

  searchedData.value.blogPosts = data?.value.blogPosts;

  // Reset loading state
  isLoading.value = false;
};

</script>

What I'm doing wrong ?

Expected behaviour

Expecting useAsyncQuery variables to update on each refresh call

Reproduction

No response

Additional context

No response

Logs

No response

@premier213
Copy link

this is async query for use interaction use, useQuery

Screenshot_20230825_161251_Chrome

@ulysse-lacour
Copy link
Author

@premier213 thank you for your help, unfortunatly couldn't make it to work with not async query for some reasons that aree beyond my comprehension....

BUT (inspired by this tutorial) I managed to have a very good result with this code :

<template>
  <div class="p-8">
    <h1 class="font-bold text-2xl mb-8">Search form</h1>
    <!-- Search input, every update of input query database -->
    <input
      type="text"
      v-model="searchText"
      name="Search"
      id="Search"
      class="border border-gray-600 rounded py-2 px-4 mr-2"
      placeholder="Search by name"
      @input="debouncedSubmitForm"
    />

    <!-- Error message -->
    <div v-if="errorMessage">{{ errorMessage }}</div>

    <!-- loading state -->
    <div v-else-if="isLoading">Loading..</div>

    <!-- Search results -->
    <div v-else-if="searchedData?.blogPosts?.data.length" class="mb-8">
      <p class="font-bold mb-2">Your search results:</p>
      <div class="flex flex-wrap">
        <div class="mr-4 mb-2 flex">
          {{ searchedData?.blogPosts }}
        </div>
      </div>

      <!-- Pagination -->
      <button v-if="currentPage > 1" @click="previousPage">PREVIOUS</button>
      <button v-if="currentPage < lastPage" @click="nextPage">NEXT</button>
    </div>

    <!-- Nothing found -->
    <p class="font-bold" v-else>No results found.</p>
  </div>
</template>

<script lang="ts" setup>
// Custom debounce function
import debounce from "@/assets/js/debounce";

// Graphql query
import { SEARCH_BLOGPOST_BY_TITLE } from "@/gql/SearchBlogPosts";

// Types
import type { BlogPostsType } from "@/types/BlogPosts";

// i18n / Language
const { locale } = useI18n();

// Search objects
const searchText = ref("");
const searchedData = ref<BlogPostsType>({ blogPosts: null });
const isLoading = ref(false);
const errorMessage = ref("");

// Pagination objects
const currentPage = ref(1);
const pageSize = ref(1); // number of item per page
const lastPage = ref(1); // stores amount of page in serach result

// Pagination functions
const previousPage = () => {
  // Decrement current page number
  currentPage.value--;
  // Search
  submitForm();
};

const nextPage = () => {
  // Increment current page number
  currentPage.value++;
  // Search
  submitForm();
};

// Search function
const submitForm = async () => {
  // Init loading state
  isLoading.value = true;

  // Query logic
  const { data, error } = await useAsyncQuery<BlogPostsType>(
    SEARCH_BLOGPOST_BY_TITLE,
    {
      Title: searchText.value,
      page: currentPage.value,
      pageSize: pageSize.value,
      locale: locale.value,
    }
  );

  // Watch for error
  if (error.value?.message) {
    errorMessage.value = error.value?.message;
  }
  // Handle search result
  else if (data?.value.blogPosts) {
    // Update displayed data based on query results
    searchedData.value.blogPosts = data?.value.blogPosts;

    // Update lastPage value with returned pageCount
    lastPage.value = data?.value.blogPosts?.meta.pagination.pageCount;
  }

  // Reset loading state
  isLoading.value = false;
};

// Debounce submit function to limit request frequency
const debouncedSubmitForm = debounce(submitForm, 500);

// Watch for locale changes to apply on search
watch(
  () => locale.value,
  async () => {
    // Reset search parameters
    currentPage.value = 1;
    pageSize.value = 1;
    lastPage.value = 1;

    // Resend search
    await submitForm();
  }
);
</script>

Hope some more senior could give feedback and provide better practices on this way of doing the search, and if done well that it could help some other bumping their heads against wall like I did !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants