I am developing some like or add to favorite kinda feature in VUE 3. But the problem i m facing here is that while i am like or unlike the specific thing it doesn’t update on the frontend UI. On refreshing it gets updated.Here i am using the backend functions to like and dislike they are working great.Help me out guys…
here is the code of Parent component
<Suspense>
<template #default>
<div class="is-flex is-1 is-flex-wrap-wrap" v-if="reciepes">
<ReciepeCard
class="card radius-small mx-2 my-3 p-3"
v-for="(reciepe, i) in reciepes"
:reciepe="reciepe"
:key="i"
:savedDishesId="savedReciepesIds"
@openReciepe="openFunc(reciepe)"
@likeIndi="isLiked(reciepe)"
>
</ReciepeCard>
</div>
</template>
</Suspense>
import ReciepeCard from '../components/reciepe-cards/reciepeCard.vue'
const reciepeStore = useReciepeStore(),
userStore = useUserStore(),
loginStore = useLoginStore(),
router = useRouter()
const reciepes = ref([]),
username = ref('User'),
savedReciepesIds = ref([])
onMounted(async () => {
fetchData()
let userId = VueCookies.get('id')
if (userId) {
let user = await userStore.fetchAccDetails(VueCookies.get('id'))
username.value = user.username
}
savedReciepesIds.value = await userStore.fetchSavedDishesId(userId)
console.log(savedReciepesIds.value)
// let like=likeNotify();
})
async function isLiked(userId) {
console.log("parent");
savedReciepesIds.value = await userStore.fetchSavedDishesId(userId)
}
async function fetchData() {
reciepes.value = await reciepeStore.getReciepes()
}
console.log(loginStore.isAuth())
function openFunc(reciepe) {
router.push({ path: `/reciepe/${reciepe._id}` })
}
</script>
THE CHILD COMPONENET
<template>
<div class="reciepe-card bg-color-white" style="cursor: pointer">
<div class="card-head" @click="emits('openReciepe')">
<figure class="">
<img :src="props.reciepe.img" alt="Recipe Image" class="image radius-default" />
</figure>
</div>
<div class="card-desc" @click="emits('openReciepe')">
<h3 class="is-size-3 color-tx-sec">{{ props.reciepe.dish_name }}</h3>
<p class="is-size-5">{{ resizeText(props.reciepe.description) + '...' }}</p>
</div>
<div class="is-flex is-justify-content-space-between is-align-items-center is- mt-3">
<p class="has-text-link" @click="emits('openReciepe')">View more</p>
<Icon
icon="ph:heart-bold"
v-if="!isLiked"
style="height: 2rem; width: 2rem"
@click="toogleLike()"
></Icon>
<Icon
icon="mdi:heart"
color="red"
v-else
style="height: 2rem; width: 2rem"
@click="toogleLike()"
></Icon>
</div>
</div>
</template>
<script setup>
import { Icon } from '@iconify/vue'
import { computed, onMounted, ref, watch } from 'vue'
import { useUserStore } from '../../stores/userStore'
import VueCookies from 'vue-cookies'
const isLiked = ref(false)
onMounted(() => {
updateLikeStats()
})
watch(
() => props.savedDishesId,
() => {
updateLikeStats()
}
)
// const isLiked = computed(() => {
// if (props.savedDishesId != null || props.savedDishesId != undefined)
// return !props.savedDishesId.includes(props.reciepe._id)
// else return false
// })
const userStore = useUserStore(),
userId = ref(VueCookies.get('id') || null)
const emits = defineEmits(['openReciepe', 'likeIndi'])
const props = defineProps({
reciepe: {
type: Object,
required: true
},
savedDishesId: {
type: Array,
required: true,
default: () => []
}
})
// Function for resizing the description
function resizeText(text) {
return text.slice(0, 120)
}
async function toogleLike() {
await userStore.toogleLikeReciepe(props.reciepe._id, { userId: userId.value })
emits('likeIndi',userId.value);
updateLikeStats()
}
function updateLikeStats() {
isLiked.value = props.savedDishesId.includes(props.reciepe._id)
console.log(isLiked.value)
}
</script>
2
Answers
Sorry guys I found the bug in my program . The bug was in the toogleLike() function.
I am assuming that your fetchdata() function in onmounted gets the data from server. Just call this function on like and dislike click.
Another way of doing this just get single call from backend which will return you updated like and dislike