N
Nuxt9mo ago
Jonathan

search page dont work

it only shows the result of the first search, to show the results of other searches, the user has to refresh the page
No description
No description
30 Replies
Jonathan
JonathanOP9mo ago
code [...search].vue:
<script setup>
const { q } = useRoute().query;

const allProducts = ref([]);

const { data } = await useFetch("/api/search.get", {
query: { q: q }
});

allProducts.value = data.value;

watch(() => q, () => data.value, { immediate: true });
</script>
<script setup>
const { q } = useRoute().query;

const allProducts = ref([]);

const { data } = await useFetch("/api/search.get", {
query: { q: q }
});

allProducts.value = data.value;

watch(() => q, () => data.value, { immediate: true });
</script>
code layouts:
<script setup lang="ts">
const searchQuery = ref("");

const handleSearch = () => {
navigateTo({ path: "/search", query: { q: searchQuery.value } });
};
</script>
<script setup lang="ts">
const searchQuery = ref("");

const handleSearch = () => {
navigateTo({ path: "/search", query: { q: searchQuery.value } });
};
</script>
Kuroro
Kuroro9mo ago
Hi, trying to help :
<script setup>
const { q } = useRoute().query;

const { data: allProducts } = await useFetch("/api/search.get", {
query: { q }
});
</script>
<script setup>
const { q } = useRoute().query;

const { data: allProducts } = await useFetch("/api/search.get", {
query: { q }
});
</script>
You don't have to add an extra "watch" method because useFetch is already listening through options obj
Jonathan
JonathanOP9mo ago
dont worked : c
Kuroro
Kuroro9mo ago
just made a typo (i forgot to delete your allProducts ref)
Jonathan
JonathanOP9mo ago
that didn't work either
<script setup>
const { q } = useRoute().query;

const categoryLabels = ["Fitness Equipment", "Clothing", "Tops Wear", "Bottom Wear", "Other"];
const priceLabels = ["Under $50.00", "$50.00 - $100.00", "$100.00 - $200.00"];

const { data: allProducts } = await useFetch("/api/search.get", {
query: { q }
});
</script>
<script setup>
const { q } = useRoute().query;

const categoryLabels = ["Fitness Equipment", "Clothing", "Tops Wear", "Bottom Wear", "Other"];
const priceLabels = ["Under $50.00", "$50.00 - $100.00", "$100.00 - $200.00"];

const { data: allProducts } = await useFetch("/api/search.get", {
query: { q }
});
</script>
F
Jonathan
JonathanOP9mo ago
does it have something to do with the backend?
No description
Jonathan
JonathanOP9mo ago
i tried do this too, but it dont work too
<script setup>
const q = ref(useRoute().query.q);
const categoryLabels = ["Fitness Equipment", "Clothing", "Tops Wear", "Bottom Wear", "Other"];
const priceLabels = ["Under $50.00", "$50.00 - $100.00", "$100.00 - $200.00"];

const { data: allProducts, refresh } = await useAsyncData("allProducts", () => $fetch("/api/search.get", {
query: q.value
}), {
watch: [q]
}
);

useHead({
title: `Search ${q.value ? `result for: ${q.value}` : "Result "} | CaliSaan`,
});
</script>
<script setup>
const q = ref(useRoute().query.q);
const categoryLabels = ["Fitness Equipment", "Clothing", "Tops Wear", "Bottom Wear", "Other"];
const priceLabels = ["Under $50.00", "$50.00 - $100.00", "$100.00 - $200.00"];

const { data: allProducts, refresh } = await useAsyncData("allProducts", () => $fetch("/api/search.get", {
query: q.value
}), {
watch: [q]
}
);

useHead({
title: `Search ${q.value ? `result for: ${q.value}` : "Result "} | CaliSaan`,
});
</script>
Kuroro
Kuroro9mo ago
You can come back to your previous version (with useFetch)
<script setup>
const { q } = useRoute().query;

const { data: allProducts } = await useFetch("/api/search", {
query: { q }
});
</script>
<script setup>
const { q } = useRoute().query;

const { data: allProducts } = await useFetch("/api/search", {
query: { q }
});
</script>
You don't have to specify ".get" in "/api/search.get" If you want to specify the method (- not needed when it's GET request because its the default value) :
const { data: allProducts } = await useFetch("/api/search", {
method: 'GET',
query: { q }
});
const { data: allProducts } = await useFetch("/api/search", {
method: 'GET',
query: { q }
});
it should work now you also should add console.log to your [...search].get.ts in order to see if you reach the endpoint (you would be able to determine your issue about your wrong API path if u had it before)
Jonathan
JonathanOP9mo ago
dont worked
Jonathan
JonathanOP9mo ago
could the problem be with the file name?
No description
No description
Jonathan
JonathanOP9mo ago
and is it possible to send a props from search.vue to layouts? if so, how do i do that? i was thinking of doing something but i don't know if it will work
Kuroro
Kuroro9mo ago
Your second capture ! You still use /api/search.get Remove .get
Jonathan
JonathanOP9mo ago
too dont work bro bro, do you know how to get a props from search and send to layouts? im thinking do a thing
Jonathan
JonathanOP9mo ago
like, i im thinking get the "refresh" from search.vue and send to layouts, for the page to be loaded every time the user performs a search
No description
Jonathan
JonathanOP9mo ago
No description
Kuroro
Kuroro9mo ago
give me a reproduction on stackblitz you don't have to create a tricky behavior to do this
Jonathan
JonathanOP9mo ago
I made a new commit on the project's github without the search bar. Is it possible for me to create a project on stackblitz with an old version of the project? i had given up on adding the search bar to the project...
manniL
manniL9mo ago
best would be providing only the search bar there 😉 you want the reproduction as minimal as possible
Jonathan
JonathanOP9mo ago
Jonathan
StackBlitz
Nuxt - Starter (forked) - StackBlitz
Create a new Nuxt project, module, layer or start from a theme with our collection of starters.
Jonathan
JonathanOP9mo ago
but it stay only on that screen, its ok?
No description
Jonathan
JonathanOP9mo ago
and my bad for my poor english
Kuroro
Kuroro9mo ago
i think we need to know your wanted behavior My guess is : - You can init the page with searched results through your query like : http://myurl.com?search=blablabla - Each time you're writing something in the search bar, it triggers again a fetch method, and write the search result in the URL query part : - So, if you type "product1" in the search bar - Your query URL will be : http://myurl.com?search=product1
Jonathan
JonathanOP9mo ago
can't it be done differently? I'd like it to be something like this: http://myurl.com/search?q=product1 like, first, if dont have a query, it to get all products, and when have a query, its to get all products from query i hope you understood, since my English isn't that good
Kuroro
Kuroro9mo ago
ok im gonna try something on a stackblitz repro then, will tell you soon
Jonathan
JonathanOP9mo ago
I managed to solve it, but there's a small bug. When I navigate between pages, go back to the home page, or click on an item, the items on the search page go into loading state, even though they shouldn't
No description
No description
Jonathan
JonathanOP9mo ago
<template>
<div class="flex max-sm:flex-col">
<main class="flex flex-col mt-12 mb-8 mx-auto max-sm:mx-[1rem] max-md:mx-[3rem] max-lg:mx-[6rem] p-0 lg:p-5 lg:px-24 lg:py-0 sm:min-w-[30rem] lg:w-full">
<h2 class="mr-auto text-lg font-semibold">{{ search ? `Results found for: ${search}` : "All Products" }}</h2>

<ul v-if="!pending && !error" class="mt-8 relative grid grid-cols-2 max-sm:grid-cols-2 max-md:grid-cols-3 md:grid-cols-3 max-lg:grid-cols-3 lg:grid-cols-4 xl:grid-cols-4 2xl:grid-cols-5 gap-7 items-start">
<li v-for="product in allProducts" :key="product.id" class="flex group border-2 border-gray">
<NuxtLink :to="`/product/${product.id}/${product.slug}`" class="p-5">
<div class="rounded-md bg-gray-200 group-hover:opacity-75">
<NuxtImg :src="product.imageSrc" :alt="product.imageAlt" loading="lazy" class="h-full w-full object-cover object-center lg:h-full lg:w-full" />
</div>
<div class="mt-4 flex justify-between">
<div>
<h3 class="text-sm text-gray-700">
<span aria-hidden="true" class="inset-0" />
{{ product.name }}
</h3>
</div>
<p class="text-sm font-medium text-gray-900">${{ product.price }}</p>
</div>
</NuxtLink>
</li>
</ul>

<SearchSkeleton v-if="pending" />

<div v-if="allProducts.length === 0" class="mt-auto h-full w-full">
<p class="text-lg text-center font-semibold">No results</p>
</div>
</main>
</div>
</template>

<script setup>
import useSearch from "~/utils/searchUtils";
const { search, doSearch } = useSearch();

const { data: allProducts, pending, error } = await useFetch("/api/search.get", {
query: { q: search }
});

useHead({
title: `Search ${search.value ? `result for: ${search.value}` : "Result "} | CaliSaan`,
});
</script>
<template>
<div class="flex max-sm:flex-col">
<main class="flex flex-col mt-12 mb-8 mx-auto max-sm:mx-[1rem] max-md:mx-[3rem] max-lg:mx-[6rem] p-0 lg:p-5 lg:px-24 lg:py-0 sm:min-w-[30rem] lg:w-full">
<h2 class="mr-auto text-lg font-semibold">{{ search ? `Results found for: ${search}` : "All Products" }}</h2>

<ul v-if="!pending && !error" class="mt-8 relative grid grid-cols-2 max-sm:grid-cols-2 max-md:grid-cols-3 md:grid-cols-3 max-lg:grid-cols-3 lg:grid-cols-4 xl:grid-cols-4 2xl:grid-cols-5 gap-7 items-start">
<li v-for="product in allProducts" :key="product.id" class="flex group border-2 border-gray">
<NuxtLink :to="`/product/${product.id}/${product.slug}`" class="p-5">
<div class="rounded-md bg-gray-200 group-hover:opacity-75">
<NuxtImg :src="product.imageSrc" :alt="product.imageAlt" loading="lazy" class="h-full w-full object-cover object-center lg:h-full lg:w-full" />
</div>
<div class="mt-4 flex justify-between">
<div>
<h3 class="text-sm text-gray-700">
<span aria-hidden="true" class="inset-0" />
{{ product.name }}
</h3>
</div>
<p class="text-sm font-medium text-gray-900">${{ product.price }}</p>
</div>
</NuxtLink>
</li>
</ul>

<SearchSkeleton v-if="pending" />

<div v-if="allProducts.length === 0" class="mt-auto h-full w-full">
<p class="text-lg text-center font-semibold">No results</p>
</div>
</main>
</div>
</template>

<script setup>
import useSearch from "~/utils/searchUtils";
const { search, doSearch } = useSearch();

const { data: allProducts, pending, error } = await useFetch("/api/search.get", {
query: { q: search }
});

useHead({
title: `Search ${search.value ? `result for: ${search.value}` : "Result "} | CaliSaan`,
});
</script>
is it possible to fix this?
manniL
manniL9mo ago
Yes, it is You check for pending while you might want to check for pending and if there is no data yet
Jonathan
JonathanOP9mo ago
I couldn't solve it : ( I think the issue lies here:
import { ref } from "vue";
import { useRoute, useRouter } from "vue-router";

const useSearch = () => {
const route = useRoute();
const router = useRouter();
const searchQuery = ref("");

const q = computed({
get: () => {
return route.query.q
},
set: (val) => {
router.push({ path: "/search", query: { q: val } })
}
});

const doSearch = () => {
q.value = searchQuery.value;
};

return {
searchQuery,
q,
doSearch,
};
};

export default useSearch;
import { ref } from "vue";
import { useRoute, useRouter } from "vue-router";

const useSearch = () => {
const route = useRoute();
const router = useRouter();
const searchQuery = ref("");

const q = computed({
get: () => {
return route.query.q
},
set: (val) => {
router.push({ path: "/search", query: { q: val } })
}
});

const doSearch = () => {
q.value = searchQuery.value;
};

return {
searchQuery,
q,
doSearch,
};
};

export default useSearch;
Jonathan
JonathanOP9mo ago
and another issue arose: the checkboxes deactivate after the page is refreshed. I was hoping for them to remain active if any of them were in the URL
No description
No description
No description
No description
Jonathan
JonathanOP9mo ago
i suspect the issue lies with the UCheckbox tags because when I log the selectedCategory and selectedPrice, the values from the URL appear
Want results from more Discord servers?
Add your server