How should I be referencing firebase data in Vue component? - firebase

I can see the data in the Vue console but I'm getting an error in the console: 'Property or method "rsvp" is not defined on the instance but referenced during render.'
How should I be referencing the firebase data?
<template>
<ul>
<li
v-for="(data, index) in rsvp"
:key="index"
>
<div
v-for="(name, index) in data.name"
:key="index"
>
{{ name }}
</div>
<div v-if="data.dietRestrictions">
Diet Restrictions: {{ data.dietRestrictions }}
</div>
</li>
</ul>
</template>
<script>
import { db } from "../../config/db";
export default {
name: "Results",
firebase: {
rsvp: db.ref("rsvp"),
},
}
</script>

I just forgot to declare rsvp in data().
data() {
return {
rsvp: {},
}
},

Related

Selected state on nav item in Next 13

I want to have a selected state on a nav item in next 13, I could find no way of getting any context on a server component so ended up with a client component like this
'use client';
import Image from 'next/image';
import Styles from '../styles/header.module.css';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
interface MainRoute {
name: string;
path: string;
index: number;
}
const mainRoutes = [
{ name: 'home', path: '/' },
{ name: 'path 2', path: '/path2' },
{ name: 'path 3', path: '/path3' },
] as MainRoute[];
export default function Header({}) {
const path = usePathname();
return (
<header>
<div className={Styles.header}>
<h1>
App title
</h1>
</div>
<div className={Styles.header}>
<ul id="mainNav">
{mainRoutes.map((route, index) => (
<li key={index}>
<Link
className={path === route.path ? Styles.selected : ''}
href={route.path}
>
{route.name}
</Link>{' '}
{index !== mainRoutes.length - 1 ? <span>|</span> : ''}
</li>
))}
</ul>
</div>
</header>
);
}
Is this the best way to achieve this basic styling?
As far as I am aware, now all of this code has to be shipped over to the client.

VueJS 3 Composition API. Can anyone explain why this will not work?

I'm loading a simple JSON file, assigning it to a reactive variable, and displaying it in the template. However, it only works partly.
{{ people }}, {{ people.People }}, and in a people.People in a v-for loop work as expected,
but accessing the people.People[0].FullName fails. But why? Any insight is appreciated.
Here is my .json
{
"People": [
{
"FullName": "The Json"
}, {
"FullName": "The Jetsons"
}
]
}
And here is the component.vue code
<template>
<h1>Test</h1>
<div>
<p>{{ people }}</p> <!-- Works and displays: { "People": [ { "FullName": "The Json" }, { "FullName": "The Jetsons" } ] } -->
<p>{{ people.People }}</p> <!-- Works and displays: [ { "FullName": "The Json" }, { "FullName": "The Jetsons" } ] -->
<p>{{ people.People[0].FullName }}</p> FAILS - Uncaught TypeError: $setup.people.People is undefined
<p v-for="(item, idx) in people.People" :key="idx">
{{ item.FullName }} <!-- Works as expected -->
</p>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
name: "Test",
setup() {
const people = ref({});
fetch('http://localhost:3000/data/people.json')
.then(response => response.json())
.then(data => people.value = data);
return {
people
}
}
}
</script>
<style>
</style>```
Thanks
At "setup time" before your json is loaded :
people = {}, so people.People[Ø] raises an error cause people.People is not defined at this moment
In your exemple
{{ people }} and {{ people.People }} display something cause it's reactive and you just don't have time to see it before the json is loaded
There is several ways to manage this. ere is two of them
Add an if
<p v-if="people.People">{{ people.People[0].FullName }}</p>
Init with default walues
const people = ref({
People: []
});

How can I use a Map with pinia/vue3

I am trying to set values in a map stored in a pinia store (persisted into localstorage)
in this minimal (non) working example pushing elements into a list works fine but adding a element into a Map does not persist.
component.vue
<script setup lang="ts">
import { useStore } from "./store"
const store = useStore()
</script>
<template>
<main>
<button
#click="store.createA"
>
Create new Array item
</button>
<ul v-if="store.array.length > 0">
<li v-for="(item) in store.array">
{{ item }}
</li>
</ul><br/>
<button
#click="store.createO"
>
Create Map Object
</button>
<ul v-if="store.mapObj.size > 0">
<li v-for="(item) in store.mapObj">
{{ item[1] }}
</li>
</ul>
</main>
</template>
store.ts
import { defineStore } from "pinia"
export const useStore = defineStore({
id: "character-manager",
state: () => ({ array: [] as Array<{key: string, value: string }>,
mapObj: new Map() as Map<string,string>}),
actions: {
createA() {
this.array.push({key: "key", value: "value"})
},
createO() {
this.mapObj.set("key", "value")
},
},
persist: {
enabled: true,
strategies: [{ storage: localStorage }],
},
})

Vuelidate vue.js latest for vue3 using the helpers.forEach approach for array of objects

Using Vuelidate vue.js latest for vue3 using the helpers.forEach approach for array of objects. I tried running the form but the validation is causing an error given as the below
Gives $response.$errors is undefined in the console
Uncaught (in promise) TypeError: $response.$errors is undefined
export default {
setup () {
const rules = {
collection: {
$each: helpers.forEach({
name: {
required
}
})
}
}
const state = reactive({
collection: [
{ name: '' },
]
})
const v = useVuelidate(rules, state)
return { v, state }
}
}
This is the template of the code
<div
v-for="(input, index) in state.collection"
:key="index"
:class="{
error: v$.collection.$each.$response.$errors[index].name.length,
}"
>
<input v-model="input.name" type="text" />
<div
v-for="error in v$.collection.$each.$response.$errors[index].name"
:key="error"
>
{{ error.$message }}
</div>
</div>
</template>
Little late, but in your template you are refering to v$.collection instead of v.collection. In your setup you are returning v and not v$
I need to use v$ as this was v$ represented a global variable based on useVuelidate

Vue/Nuxt - Iterating Through Firestore Collection of Documents using v-for

First Vue/Firebase project. Using NuxtJS (with Vue v2.x) with Vuetify and Firestore. Attempting to iterate through a collection of documents and render Vuetify Card components with relevant data. Currently, I'm getting a list of components with the exact same data from a single Document. I able to log Collection items to the console, so I know the data is arriving correctly.
<template>
<section class="container">
<div>
<ul v-for="article in articles" id="articleCardList" :key="article">
<li>
<v-card dark>
<div class="d-flex flex-no-wrap justify-space-between">
<v-avatar class="ma-3" size="125" tile>
<v-img :key="article.thumbnail" :src="thumbnail"></v-img>
</v-avatar>
<div>
<v-card-title :key="article.title" class="text-h5">{{
title
}}</v-card-title>
<v-card-subtitle :key="article.description">{{
description
}}</v-card-subtitle>
<v-card-actions>
<v-card-text
:key="article.source"
class="ml-2 mt-3"
fab
icon
height="40px"
right
width="40px"
>{{ source }}
</v-card-text>
<v-card-text
:key="article.date"
class="ml-2 mt-3"
fab
icon
height="40px"
right
width="40px"
>{{ date }}
</v-card-text>
</v-card-actions>
</div>
</div>
</v-card>
</li>
</ul>
</template>
<script>
import { fireDb } from '~/plugins/firebase.js'
export default {
data() {
return {
writeSuccessful: false,
readSuccessful: false,
articles: this.articles,
}
},
methods: {
async readFromFirestore() {
fireDb
.collection('autoracing_articles')
.get()
.then((querySnapShot) => {
querySnapShot.forEach((doc) => {
this.articles = [
this.id,
this.title,
this.description,
this.thumbnail,
this.date,
this.link,
this.source,
]
console.log(this.articles)
})
})
},
},
}
</script>
It doesn't look like articles is populated correctly.
To collect all the documents into an array, initialize this.articles to an empty array, then use Array.prototype.push() to append an object of the document fields:
export default {
data() {
return {
articles: []
}
},
methods: {
async readFromFirestore() {
this.articles = []
fireDb
.collection('autoracing_articles')
.get()
.then((querySnapShot) => {
querySnapShot.forEach((doc) => {
this.articles.push({
id: doc.id,
title: doc.data().title,
description: doc.data().description,
thumbnail: doc.data().thumbnail,
date: doc.data().date,
link: doc.data().link,
source: doc.data().source,
})
})
})
},
}
}

Resources