Network Load Fix

User
<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

Assistant
The issue where `fetchPortfolioItems` returns an empty array **intermittently** (especially on first load or network reconnect) but returns data after some change on the page suggests a **timing issue**, possibly related to:

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!

User
You're offline or experiencing network issues. Some features may not work.

v-if not working in snackbar

Assistant
In Vuetify 3, “ **does not use** `v-if` for showing/hiding. Instead, it relies on the **`v-model` binding**, typically with a `ref` like `showNetworkSnackbar`.

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!

User
<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

User
snackbar component not working in FrontLayout.vue
Assistant
Thanks for the follow-up. The issue you're facing likely comes down to **how you're using the `v-model` binding on a prop**, which Vue does **not allow directly**. Here's the breakdown and fix.

### ❌ 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!

User
snackbar permanentaly
Assistant
If you want your “ to stay **permanently visible** (i.e., never auto-dismiss), just set `:timeout="0"`.

### ✅ 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.

User
not showing if timeout 0
Assistant
If your “ is **not showing when `timeout: 0`**, it's likely due to how Vuetify handles *"open forever"* snackbars — they **require manual dismissal** and sometimes won’t animate properly unless the value is toggled correctly or the Snackbar is visible in the DOM at mount.

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.

Leave a Comment

Your email address will not be published. Required fields are marked *