Everything was fine yesterday. Everything was clearly displayed. But today nothing is displayed. And it does not give any errors. Just some miracles. When will firebase stop buggy
<template>
<div class="admin">
<h1> Hi, {{ userProfile.name }} </h1>
<v-row>
<v-col md="4" v-for="(user, index) in users" :key="user.id">
<v-card>
<v-img
v-if="user.image"
height="250"
:src="user.image"
lazy-src="https://via.placeholder.com/250"
>
</v-img>
<v-card-title> {{ user.name }} </v-card-title>
<v-card-text>
<p class="subtitle-1">Email: {{ user.email }}</p>
<p class="subtitle-1">Phone: {{ user.phone }}</p>
<p>{{ user.description }}</p>
</v-card-text>
<v-card-actions>
<Contacts :user="user" :index="index" />
<v-btn color="red">Delete</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</div>
</template>
SCRIPT
<script>
import { mapState } from 'vuex'
import Contacts from '../views/Contacts.vue'
import { auth, storage, adminPanel } from '../firebase'
export default {
components: {
Contacts
},
data() {
return {
users: []
}
},
computed: {
...mapState(['userProfile'])
},
methods: {
async getUsers() {
try {
const querySnapshot = await adminPanel.where('userId', '==', auth.currentUser.uid).get()
querySnapshot.forEach( async (doc) => {
let img = ''
if(doc.data().image) {
img = await storage.ref().child(doc.data().image).getDownloadURL()
}
this.users.push({
id: doc.id,
name: doc.data().name,
email: doc.data().email,
phone: doc.data().description,
image: img,
img: doc.data().image
})
} )
} catch(e) {
console.log(e)
}
}
},
async mounted() {
await this.getUsers()
}
}
</script>
Are these firebase glitches? If so, how to get rid of them give advice? What should I do? how to make it work back?
Related
I'm trying to create SnackBarComponent.vue so I can implement it in my BaseTemplate.vue where I have my main menu that references the other router-view components.
This would be my BaseComponent.Vue
<template>
<v-app id="inspire">
<v-navigation-drawer
v-model="drawer"
app
clipped
>
<v-list dense>
<v-list-item
v-for="item in items"
:key="item.title"
:to="item.to"
:active-class="`primary white--text`"
link
>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar
app
clipped-left
color="blue"
dark
>
<v-app-bar-nav-icon #click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title>Title</v-toolbar-title>
</v-app-bar>
<v-main>
<v-container fluid style="padding:30px">
<transition name="component-fade" mode="out-in">
<router-view></router-view>
</transition>
</v-container>
</v-main>
<template>
<v-snackbar
v-model="snackbar"
:timeout="timeoutSnackBar"
>
{{ textSnackBar }}
</v-snackbar>
</template>
</v-app>
</template>
<script>
export default {
data: () => ({
snackbar: false,
timeoutSnackBar: -1,
textSnackBar: '',
methods:{
SnackNotification(time,text){
this.snackbar = true
this.timeoutSnackBar: time
this.textSnackBar: text
}
}
drawer: null,
items: [
{
title: "Home",
icon: "mdi-view-dashboard",
to: "/"
},
{
title: "Users",
icon: "mdi-account",
to: "/users"
},
]
}),
}
</script>
and i try use in de UserComponent.vue
<template>
<v-card
class="mx-auto"
max-width="344"
outlined
>
<v-list-item three-line>
<v-list-item-content>
<div class="overline mb-4">
OVERLINE
</div>
<v-list-item-title class="headline mb-1">
Headline 5
</v-list-item-title>
<v-list-item-subtitle>Greyhound divisely hello coldly fonwderfully</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-avatar
tile
size="80"
color="grey"
></v-list-item-avatar>
</v-list-item>
<v-card-actions>
<v-btn
outlined
rounded
text
>
Button
</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
export default {
created() {
this.users();
},
methods: {
users: function() {
axios
.get('/api/users')
.then(response => {
this.users = response.data.data
})
.catch(error => {
this.errored = true
})
.finally(() => {
if (this.firstLoad) this.firstLoad = false
this.loading = false;
this.SnackNotification(2000,'Hi, im a notification')
})
},
}
</script>
My app.js is this.
import App from './components/BaseTemplate.vue'
const app = new Vue({
el: '#app',
render: h => h(App),
vuetify: new Vuetify(),
router
})
had the idea to do it this way but I think I am quite wrong to do this global implementation, I looked for some options but they used NuxtJS and it was not really what I had in mind, any recommendation that could give me how to do it? thank you.
You could add the snack bar in vue.app as global snackbar with vuex.
Example:
App.vue
<template>
<v-app>
...
<v-main>
<router-view />
</v-main>
...
<v-snackbar v-model="snackbar.active" :timeout="-1" :color="snackbar.color">
{{ snackbar.message}}
<template v-slot:action="{ attrs }">
<v-btn text v-bind="attrs" #click="snackbar.active = false">
Close
</v-btn>
</template>
</v-snackbar>
</v-app>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "App",
computed: {
...mapState(["snackbar"])
}
};
</script>
Index.js (store)
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
snackbar: { active: false, color: "", message: "" }
},
mutations: {
SET_SNACKBAR(state, snackbar) {
state.snackbar = snackbar;
}
},
actions: {
snackBar({ commit }, message) {
commit("SET_SNACKBAR", {
active: true,
color: "success", // You can create another actions for diferent color.
message: message
});
}
}
});
Now in any router view you can active the snackbar like this
Example.vue
<template>
...
<v-btn #click="showSnackBar()">
Show SnackBar!
</v-btn>
...
</template>
<script>
import { mapActions} from "vuex";
export default {
methods: {
...mapActions(["snackBar"]),
showSnackBar() {
this.snackBar("Hi, I'm snackbar");
}
}
};
</script>
Please see my answer here for a very similar problem. In that case, they wanted a global 'confirm dialog' but in your case it's a 'global snackbar'
The code that I posted in that answer can be used for a snackbar instead of a dialog with very minimal modification. In fact, in my projects I usually go ahead and add both because they're so useful.
how to pass variable between to vue file ?
Hello, this is my file SendCode.vue has variable NewEmail which I want to use it in another file changePass.vue .
Is there anyway to sole this ?
Can someone help me ? Thanks
<template>
<v-app id="inspire">
<v-content>
<v-container class="fill-height" fluid>
<v-row align="center" justify="center">
<v-col cols="12" sm="8" md="4">
<v-card class="elevation-12">
<v-toolbar color="#ff8c00">
<v-toolbar-title>Glömt lösenord!</v-toolbar-title>
</v-toolbar>
<v-card-text>
Skrive ditt email.
<v-form>
<v-text-field v-model="email"
:error-messages="emailErrors"
label="E-mail"
required
#input="$v.email.$touch()"
#blur="$v.email.$touch()"></v-text-field>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn #click="getCode" color="primary">Skicka koden</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</v-content>
</v-app>
</template>
<script>
import axios from 'axios'
import router from '#/router.js'
import { validationMixin } from 'vuelidate'
import { required, email } from 'vuelidate/lib/validators'
export default {
mixins: [validationMixin],
validations: {
email: { required, email },
checkbox: {
checked(val) {
return val
}
}
},
props: {
source: String,
},
data: () => ({
email: ""
}),
methods: {
getCode: async function() {
let obj = {
"email": this.email,
};
let NewEmail = this.email;
let response = await this.$store.dispatch("getCode", obj);
//console.log(email)
//console.log(this.email)
if (response.status == 200) {
setTimeout(function() {
router.push({
path: 'ChangePass'
});
}, 500);
}
}
}
}
</script>
I want to use/pass variable NewEmail in this file from SendCode.vue file
I am new in vue and javascript so I do not know how to do this.
<template>
<v-app id="inspire">
<v-content>
<v-container class="fill-height" fluid>
<v-row align="center" justify="center">
<v-col cols="12" sm="8" md="4">
<v-card class="elevation-12">
<v-toolbar color="#ff8c00">
<v-toolbar-title>ÄNDRA LÖSENORDET</v-toolbar-title>
</v-toolbar>
<v-card-text>
<v-form>
<v-text-field :error="pass1Error" label="Koden" v-model="code1" type="password" />
<v-text-field :error="pass2Error" label="Lössenord" v-model="newPassword" type="password" />
<v-text-field :error="pass1Error" label="Samma Lössenord" v-model="rePassword" type="password" />
</v-form>
</v-card-text>
<v-alert v-if="passError" type="error">
password are not same
</v-alert>
<v-alert v-if="passwordChanged" type="success">
Password has been updated!
</v-alert>
<v-card-actions>
<v-spacer />
<v-btn #click="change" color="primary">Ändra</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</v-content>
</v-app>
</template>
<script>
import axios from 'axios'
import SendCode from "#/views/SendCode.vue";
import { validationMixin } from 'vuelidate'
import { required, email } from 'vuelidate/lib/validators'
export default {
mixins: [validationMixin],
validations: {
email: { required, email },
checkbox: {
checked(val) {
return val
}
}
},
props: {
source: String,
},
data: () => ({
code1: "",
newPassword: "",
rePassword: ""
}),
methods: {
change: async function() {
let obj = {
"code1": this.code1,
"newPassword": this.newPassword,
"rePassword": this.rePassword,
};
console.log(obj)
let response = await this.$store.dispatch("changePass", obj);
}
}
}
</script>
We recommend that you use Vuex (State management) for easy transfer and management of data through pages
Documentation:
https://vuex.vuejs.org/
If its only a variable with some value in it you can store it in localstorage i assume.
So in your function where you have the data you want to pass add:
localStorage.setItem('email', variable).
This works as a key value pair where email is the key and the variable is the data you want to access.
Then where you want to access the data you can use:
localStorage.getItem('email')
You probably don't want to do what you're trying to do, but would be better off with state management (vuex/pinia/genericVueStore), or, if you want to pass the data between components in the same app (same project), then the main method is $emits and $props. Check Vue documentation to see if that is what you want, which it probably is.
Nevertheless, within a Vue project, you can generally use Node/ES methods. So, the following would be fine, and would fit into the "composables" category if they weren't ".vue" files.
>> file1.vue
<script setup>
const oneData = "this_text"
export {oneData}
...
>> file2.vue
import {oneData} from "#/file1.vue"
console.log(oneData}
This would be an anti-pattern. Just follow the documentation for the standard things people try to accomplish.
I have an array of object - some of which need to have a property tweaked depending on their value. In a v-for loop, how do I ammend a value, is this what computed is for?
I have tried creating and accessing a computed value but I suspect I am misunderstanding the order of events here.
<template>
<v-container grid-list-md>
<v-layout row wrap>
<v-flex xs6 md3 v-for="item in items" :key="item.da_id">
<v-card>
<v-img
:src="item.imgUrl"
aspect-ratio="2.75"
></v-img>
<v-card-title primary-title>
<div>
<h3 class="headline mb-0">{{item.title}}</h3>
</div>
</v-card-title>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import axios from 'axios'
export default {
data() {
imgUrl: {
return ''
}
},
async asyncData ({ params }) {
let {data} = await axios.get(`http://XXX.XXX.XXX.192:8080/api/collection/${params.id}`)
return { items: data }
},
computed: {
imgUrl(item) {
console.log(this.items.map(item))
return 'https://aijxxppmen.cloudimg.io/crop/500x500/tjpg/https://dartmoorpublic.s3-eu-west-1.amazonaws.com/' + this.items.file_id
}
}
}
</script>
I am expecting each v-card :src value to be different and based on the computed function I have created. I am getting undefined.
You are not looking for a computed property. Computed properties are properties of the Vue instance, not of the elements in your items array. You will want to use a method instead:
<template>
<v-container grid-list-md>
<v-layout row wrap>
<v-flex xs6 md3 v-for="item in items" :key="item.da_id">
<v-card>
<v-img
:src="imgUrl(item)"
aspect-ratio="2.75"
></v-img>
<v-card-title primary-title>
<div>
<h3 class="headline mb-0">{{item.title}}</h3>
</div>
</v-card-title>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
import axios from 'axios'
export default {
data() {
imgUrl: {
return ''
}
},
async asyncData ({ params }) {
let {data} = await axios.get(`http://XXX.XXX.XXX.192:8080/api/collection/${params.id}`)
return { items: data }
},
methods: {
imgUrl(item) {
console.log(item)
return 'https://aijxxppmen.cloudimg.io/crop/500x500/tjpg/https://dartmoorpublic.s3-eu-west-1.amazonaws.com/' + item.file_id
}
}
}
I am getting this error when I edit one of the text fields (which updates the store):
I've already tried putting #change and v-model on the text fields and that is not proper. Need to find a proper way to mutate the state on an event triggered by the text field(s).
Example:
Profile.vue:
<v-text-field #change="setProfile(profileData)" v-model="profileData.groupName" label="Group Name"></v-text-field>
Here is my code:
Profile.vue:
<v-text-field #change="set" v-model="profileData.groupName" label="Group Name"></v-text-field>
Profile.vue Javascript:
import { mapGetters, mapMutations } from "vuex";
export default {
name: "Profile",
created() {
delete this.profileData;
this.profileData = JSON.parse(JSON.stringify(this.getProfile()));
console.log(this.profileData);
},
data() {
return {
profileData: {
groupName: null,
groupClid: null,
groupContact: null
}
};
},
methods: {
set() {
this.$store.commit("setProfile", this.profileData);
},
...mapGetters(["getProfile"]),
...mapMutations(["setProfile"])
}
}
build.js --> store.js:
const state = {
profile: {
"groupName": "Happy group",
"groupNumber": "9999999999",
"groupContact": "Bob Ross"
}
};
const getters = {
getProfile: (state) => state.profile,
};
const actions = { };
const mutations = {
setProfile: (state, profile) => (state.profile = profile)
};
export default {
state,
getters,
actions,
mutations,
}
Answer:
Remove delete this.profileData from created()
Change the set() to `setData'
Change to Object.assign (shouldn't matter if you use string->parse or Object.assign)
Put one change event on the card, above the text fields. This way, we don't have to duplicate the vue-style event listener.
<template >
<v-container fluid>
<v-layout row wrap fill-height>
<v-flex xs6>
<v-card elevation="10">
<v-card-title primary-title class="pb-0">
<div>
<h3 class="headline mb-0 pb-0">Group Information</h3>
</div>
</v-card-title>
<v-card-text #change="setData">
<v-container fluid>
<v-layout align-center row wrap>
<v-flex xs3>
<v-responsive>Group Name:</v-responsive>
</v-flex>
<v-flex xs9>
<v-text-field v-model="profileData.groupName" label="Group Name"></v-text-field>
</v-flex>
</v-layout>
</v-container>
</v-card-text>
</v-card>
</v-flex>
</v-layout>
<v-spacer></v-spacer>
</v-container>
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
export default {
name: "Profile",
created() {
this.profileData = Object.assign({}, this.getProfile());
},
data() {
return {
profileData: {}
};
},
methods: {
setData() {
this.setProfile(this.getData());
},
getData() {
return Object.assign({}, this.profileData);
},
...mapGetters(["getProfile"]),
...mapMutations(["setProfile"])
}
};
</script>
i'm learning vuetify framework, i managed to use most of the components but i have a problem with autocomplete component.
Using it from scratch works fine, bug if i try to set value during creation it doesn't work at all.
I tried to extend one of the vuetify example but without success.
i would like to load first value from the API during creation but it stays empty.
Thanks for your help.
new Vue({
el: '#app',
data: () => ({
descriptionLimit: 60,
entries: [],
isLoading: false,
model: null,
search: "Cats"
}),
created :function() {
model={"API":"Cats","Description":"Pictures of cats from Tumblr","Auth":"","HTTPS":true,"Cors":"unknown","Link":"https://thecatapi.com/docs.html","Category":"Animals"},
search="Cats"
},
computed: {
fields () {
if (!this.model) return []
return Object.keys(this.model).map(key => {
return {
key: key,
value: this.model[key] || 'n/a'
}
})
},
items () {
return this.entries.map(entry => {
const Description = entry.Description.length > this.descriptionLimit
? entry.Description.slice(0, this.descriptionLimit) + '...'
: entry.Description
return Object.assign({}, entry, { Description })
})
}
},
watch: {
search (val) {
// Items have already been loaded
if (this.items.length > 0) return
this.isLoading = true
console.log("loadgin data")
// Lazily load input items
axios.get('https://api.publicapis.org/entries')
.then(res => {
const { count, entries } = res.data
this.count = count
this.entries = entries
})
.catch(err => {
console.log(err)
})
.finally(() => (this.isLoading = false))
}
}
})
<div id="app">
<v-app id="inspire">
<v-card
color="red lighten-2"
dark
>
<v-card-title class="headline red lighten-3">
Search for Public APIs
</v-card-title>
<v-card-text>
Explore hundreds of free API's ready for consumption! For more information visit
<a
class="grey--text text--lighten-3"
href="https://github.com/toddmotto/public-apis"
target="_blank"
>the Github repository</a>.
</v-card-text>
<v-card-text>
<v-autocomplete
v-model="model"
:items="items"
:loading="isLoading"
:search-input.sync="search"
color="white"
hide-no-data
hide-selected
item-text="Description"
item-value="API"
label="Public APIs"
placeholder="Start typing to Search"
prepend-icon="mdi-database-search"
return-object
></v-autocomplete>
</v-card-text>
<v-divider></v-divider>
<v-expand-transition>
<v-list v-if="model" class="red lighten-3">
<v-list-tile
v-for="(field, i) in fields"
:key="i"
>
<v-list-tile-content>
<v-list-tile-title v-text="field.value"></v-list-tile-title>
<v-list-tile-sub-title v-text="field.key"></v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-expand-transition>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
:disabled="!model"
color="grey darken-3"
#click="model = null"
>
Clear
<v-icon right>mdi-close-circle</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</v-app>
</div>
If this is the code you are trying to use then you are missing a ',' at the end of the "model".
created :function() {
model={...}, <----
search="Cats"
},
blalan05 on the discrod channel just give me the reply : my created function was garbled.
new Vue({
el: '#app',
data: () => ({
descriptionLimit: 60,
entries: [],
isLoading: false,
model: null,
search: "Cats"
}),
created () {
this.model = {"API":"Cats","Description":"Pictures of cats from Tumblr","Auth":"","HTTPS":true,"Cors":"unknown","Link":"https://thecatapi.com/docs.html","Category":"Animals"},
this.search = "Cats"
},
computed: {
fields () {
if (!this.model) return []
return Object.keys(this.model).map(key => {
return {
key: key,
value: this.model[key] || 'n/a'
}
})
},
items () {
return this.entries.map(entry => {
const Description = entry.Description.length > this.descriptionLimit
? entry.Description.slice(0, this.descriptionLimit) + '...'
: entry.Description
return Object.assign({}, entry, { Description })
})
}
},
watch: {
search (val) {
// Items have already been loaded
if (this.items.length > 0) return
this.isLoading = true
console.log("loadgin data")
// Lazily load input items
axios.get('https://api.publicapis.org/entries')
.then(res => {
const { count, entries } = res.data
this.count = count
this.entries = entries
})
.catch(err => {
console.log(err)
})
.finally(() => (this.isLoading = false))
}
}
})
<div id="app">
<v-app id="inspire">
<v-card
color="red lighten-2"
dark
>
<v-card-title class="headline red lighten-3">
Search for Public APIssss
</v-card-title>
<v-card-text>
Explore hundreds of free API's ready for consumption! For more information visit
<a
class="grey--text text--lighten-3"
href="https://github.com/toddmotto/public-apis"
target="_blank"
>the Github repositoryyy</a>.
</v-card-text>
<v-card-text>
<v-autocomplete
v-model="model"
:items="items"
:loading="isLoading"
:search-input.sync="search"
color="white"
hide-no-data
hide-selected
item-text="Description"
item-value="API"
label="Public APIs"
placeholder="Start typing to Search"
prepend-icon="mdi-database-search"
return-object
></v-autocomplete>
</v-card-text>
<v-divider></v-divider>
<v-expand-transition>
<v-list v-if="model" class="red lighten-3">
<v-list-tile
v-for="(field, i) in fields"
:key="i"
>
<v-list-tile-content>
<v-list-tile-title v-text="field.value"></v-list-tile-title>
<v-list-tile-sub-title v-text="field.key"></v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-expand-transition>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
:disabled="!model"
color="grey darken-3"
#click="model = null"
>
Clear
<v-icon right>mdi-close-circle</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</v-app>
</div>