Network Load Fix
April 19, 2025 · AI Conversations
<script>
import { ref,onMounted,watchEffect,watch } from 'vue'
import TheQuote from './TheQuote.vue'
import { useTrueFalseStore } from '@/stores/truefalse';
import { useLoadingStore } from '@/stores/loading';
import { useNetworkStore } from '@/stores/network';
const mainAdminEmail = import.meta.env.VITE_MAIN_ADMIN_EMAIL;
import {
fetchPortfolioItems,
fetchPortfolioCategories
} from '@/dbstore/firebase/myPortfolio'
const truefalseStore = useTrueFalseStore();
const networkStore = useNetworkStore();
const loadingStore = useLoadingStore();
const tab = ref(null)
interface PortfolioItem {
id: string
title: string
description: string
url: string
image: string
}
interface PortfolioCategory {
id: string
image: string
name: string
url: string
}
const expandedPosts = ref<Record<string, boolean>>({});
const portfolioItems = ref<PortfolioItem[]>([])
const loadItems = async () => {
console.log('Loading portfolio items...');
loadingStore.setLoading(true);
try {
portfolioItems.value = await fetchPortfolioItems() as PortfolioItem[];
expandedPosts.value = {};
console.log(portfolioItems.value);
}catch(err)
{
}finally{
loadingStore.setLoading(false);
}
}
const portfolioCategories = ref<PortfolioCategory[]>([])
const loadCategories = async () => {
portfolioCategories.value = await fetchPortfolioCategories() as PortfolioCategory[];
}
onMounted(() => {
if(networkStore.isOnline){
loadItems();
loadCategories();
}
});
const toggleExpand = (postId: string) => {
expandedPosts.value[postId] = !expandedPosts.value[postId];
};
const showAlert=ref(false);
const loadTab = async () => {
truefalseStore.setTrueFalse(false);
}
watch(
() => networkStore.isOnline,
(isOnline) => {
console.log(isOnline ? 'Online23 ✅' : 'Offline ❌');
if (isOnline) {
loadItems();
}
}
);
</script>
Portfolio
Contact Us
Share Requirement
{{ item.title }}
{{ item.description }}
dailymediain@gmail.com
{{ mainAdminEmail }}
Please feel free to contact us
+91 9718395506
watch(
() => networkStore.isOnline,
(isOnline) => {
console.log(isOnline ? 'Online23 ✅' : 'Offline ❌');
if (isOnline) {
loadItems();
}
}
);
watch is working but fetchportfilio items return empty array some times and when we change anything on the page then it teturn
1. **`networkStore.isOnline` not being reactive or updated properly when component is mounted.**
2. **Firestore not ready or responding slowly during first fetch.**
3. **`loadItems()` not triggered correctly during the initial mount or network change.**
—
### ✅ Fix Strategy:
We’ll ensure:
– The network status is reliably reactive.
– Initial `onMounted()` logic is robust.
– We delay `loadItems()` slightly on network reconnect to give Firestore time to re-establish the connection.
—
### 🔧 Fixes in Your Script:
Update the `onMounted` block and the `watch()` for network status like this:
onMounted(() => {
if (networkStore.isOnline) {
loadItems();
loadCategories();
} else {
// Fallback watcher in case online status was false on mount but changes shortly
const unwatch = watch(
() => networkStore.isOnline,
(isOnline) => {
if (isOnline) {
loadItems();
loadCategories();
unwatch(); // Remove this watcher after one successful load
}
}
);
}
});
Add a **debounced or delayed load** on network reconnect to allow Firestore sync:
watch(
() => networkStore.isOnline,
(isOnline) => {
console.log(isOnline ? 'Online ✅' : 'Offline ❌');
if (isOnline) {
// Delay to allow Firebase to stabilize
setTimeout(() => {
loadItems();
}, 500); // Adjust delay as needed
}
}
);
—
### 🔄 Optional: Add Retry Logic in `loadItems`
Sometimes, Firebase may respond with an empty array on reconnect due to a temporary desync. You can retry:
const loadItems = async (retryCount = 0) => {
console.log('Loading portfolio items...');
loadingStore.setLoading(true);
try {
const items = await fetchPortfolioItems() as PortfolioItem[];
if (items.length === 0 && retryCount < 3) {
setTimeout(() => loadItems(retryCount + 1), 300);
return;
}
portfolioItems.value = items;
expandedPosts.value = {};
console.log(items);
} catch (err) {
console.error(err);
} finally {
loadingStore.setLoading(false);
}
};
—
### ✅ Summary
– Use a `watch` fallback in case the user is offline during `onMounted`.
– Add a small delay after network reconnect to ensure Firebase is synced.
– (Optional) Add retry logic if empty array is returned immediately.
Let me know if you'd like this wrapped into a composable for reusability!
v-if not working in snackbar
If you're using `v-if`, it may cause issues because:
– The component is mounted/unmounted entirely, which interferes with Vuetify’s internal animations and reactivity.
—
### ✅ Solution: **Remove `v-if` and rely only on `v-model`**
Make sure `showNetworkSnackbar` is defined as a `ref` in “:
const showNetworkSnackbar = ref(false);
Then control it like this:
watch(() => networkStore.isOnline, (isOnline) => {
if (!isOnline) {
showNetworkSnackbar.value = true;
}
});
—
### ✅ Correct “ Usage:
<v-snackbar
v-model="showNetworkSnackbar"
:timeout="4000"
location="top right"
color="warning"
>
You're offline or experiencing network issues. Some features may not work.
</v-snackbar>
—
### 💡 Optional: Add “Close” Button
<template>
<v-snackbar
v-model="showNetworkSnackbar"
:timeout="4000"
location="top right"
color="warning"
>
You're offline or experiencing network issues.
<template #actions>
<v-btn icon @click="showNetworkSnackbar = false">
<v-icon>mdi-close</v-icon>
</v-btn>
</template>
</v-snackbar>
</template>
Let me know if you'd like it to auto-appear on reconnect too!
<script>
import { ref } from 'vue'
const props = defineProps({
show: {
type: Boolean,
default: false
},
timeout: {
type: Number,
default: 4000
},
location: {
type: String,
default: 'bottom right'
},
color: {
type: String,
default: 'warning'
}
})
</script>
snackbar component not working in FrontLayout.vue
—
### ❌ Issue: `:v-model="show"` on “
This is **incorrect** usage because:
– `v-model` is sugar syntax for binding `modelValue` and emitting `update:modelValue`.
– You're trying to bind directly to a **prop (`show`)**, which is **read-only** in child components.
—
### ✅ Solution: Use a `localShow` ref and `emit`
Update your “ to manage the internal state:
<script setup>
import { ref, watch } from 'vue'
const props = defineProps({
show: Boolean,
timeout: {
type: Number,
default: 4000
},
location: {
type: String,
default: 'bottom right'
},
color: {
type: String,
default: 'warning'
}
})
const emit = defineEmits(['update:show'])
const localShow = ref(props.show)
// Sync prop to local ref when prop changes
watch(() => props.show, (val) => {
localShow.value = val
})
// Emit update when snackbar closes
watch(localShow, (val) => {
if (val !== props.show) {
emit('update:show', val)
}
})
</script>
Update your template:
<template>
<v-snackbar
v-model="localShow"
:timeout="timeout"
:location="location"
:color="color"
>
<slot />
</v-snackbar>
</template>
—
### ✅ Usage in `FrontLayout.vue`
<template>
<CustomSnackbar v-model:show="showNetworkSnackbar">
You're offline or experiencing network issues.
</CustomSnackbar>
</template>
<script setup>
import CustomSnackbar from '@/components/CustomSnackbar.vue'
import { ref } from 'vue'
const showNetworkSnackbar = ref(false)
</script>
—
Let me know if you'd like to auto-trigger it on `networkStore.isOnline === false` as well!
—
### ✅ Update in your Snackbar Component:
<v-snackbar
v-model="localShow"
:timeout="0"
:location="location"
:color="color"
>
<slot />
</v-snackbar>
Or allow it to be configurable via prop and default it to 0:
const props = defineProps({
show: Boolean,
timeout: {
type: Number,
default: 0 // 👈 stays visible permanently
},
location: {
type: String,
default: 'bottom right'
},
color: {
type: String,
default: 'warning'
}
})
—
### ✅ Usage in Parent:
<CustomSnackbar v-model:show="showNetworkSnackbar">
You're offline or experiencing network issues.
</CustomSnackbar>
The Snackbar will now **stay open until manually closed** (e.g., via a close button or changing `showNetworkSnackbar = false`).
Let me know if you'd like to include a dismiss button too.
Here’s how to **fix it reliably**:
—
### ✅ Make Snackbar Permanent & Ensure It Shows
#### 1. Use `timeout="Infinity"` instead of `0`
Vuetify 3 prefers `timeout="Infinity"` for permanent visibility:
<v-snackbar
v-model="localShow"
:timeout="Infinity"
:location="location"
:color="color"
>
<slot />
</v-snackbar>
> `0` might get interpreted as no timeout setup at all and not trigger display in some Vuetify versions.
—
#### 2. Make Sure `localShow` is `true` **after** mount
If you're setting `localShow = true` immediately on mount, add a slight delay:
onMounted(() => {
setTimeout(() => {
localShow.value = true;
}, 100); // ensure DOM is ready
});
—
#### 3. Add Close Button (Optional)
<template #actions>
<v-btn icon @click="localShow = false">
<v-icon>mdi-close</v-icon>
</v-btn>
</template>
—
### ✅ Final Version of Snackbar Component
<template>
<v-snackbar
v-model="localShow"
:timeout="Infinity"
:location="location"
:color="color"
>
<slot />
<template #actions>
<v-btn icon @click="localShow = false">
<v-icon>mdi-close</v-icon>
</v-btn>
</template>
</v-snackbar>
</template>
<script setup>
import { ref, watch } from 'vue'
const props = defineProps({
show: Boolean,
timeout: { type: Number, default: Infinity },
location: { type: String, default: 'bottom right' },
color: { type: String, default: 'warning' }
})
const emit = defineEmits(['update:show'])
const localShow = ref(props.show)
watch(() => props.show, val => (localShow.value = val))
watch(localShow, val => emit('update:show', val))
</script>
Let me know if you'd like it to auto-reopen on certain conditions like going offline again.