Call $emit after dispatch action in Vuejs - vue.js

I have a parent component:
<template>
<div class="w-full">
<div class="card-body">
<city-edit-form :form="form" :resource="resource" #save_resource="func">
</city-edit-form>
</div>
</div>
</template>
<script>
export default {
methods: {
func() {
console.log("test");
}
}
};
</script>
And child component:
<template>
<div>
<form action="#" method="POST" #submit.prevent="submit" v-else>
<button type="submit" class="btn-green">Save</button>
</form>
</div>
</template>
<script>
import { UPDATE_RESOURCE } from "../../../Stores/action-types";
export default {
props: {
form: { required: true },
resource: { required: true }
},
methods: {
submit() {
this.$store
.dispatch(`city/${UPDATE_RESOURCE}`, this.form)
.then(() => this.$emit("save_resource"));
}
}
};
</script>
And action is:
[UPDATE_RESOURCE]({ commit, state }, form) {
commit(SET_LOADING, true);
return ResourceService.update(state.resource.id, form)
.then(({ data }) => {
commit(SET_RESOURCE, data);
})
.catch(errors => {
commit(SET_ERRORS, errors.response.data);
})
.finally(() => commit(SET_LOADING, false));
});
},
When I submit form, action has been dispatched, but nothing emitted.
Nothing logged in console. Where I make mistake?
update
When I check Vue toolbar's Event tab, I see this:
I think event has been emmitted, but console.log logs nothing in console! So wired!

Use return keyword while resolve or reject is triggered
[UPDATE_RESOURCE]({ commit, state }, form) {
commit(SET_LOADING, true);
return new Promise((resolve, reject) => {
ResourceService.update(state.resource.id, form)
.then(({ data }) => {
commit(SET_RESOURCE, data);
return resolve();
})
.catch(errors => {
commit(SET_ERRORS, errors.response.data);
return reject();
})
.finally(() => commit(SET_LOADING, false));
});
},

instead of emitting events (nothing wrong with that) you could use mapGetters
<template>
<div class="w-full">
<div class="card-body">
<city-edit-form :form="form" :resource="myResource">
</city-edit-form>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters({
myResource: 'Stores/action-types/SET_RESOURCE', <---- needs to be modified
}),
}
};
</script>
this is assuming you have made any getters

Related

Vue: Pinia state property doesn't update in component with node-forge

I read the other stackoverflow questions but does not help. I use pinia=2.0.27. I could extend the example if neccessary.
I have a component with a button with a spinner.
<template>
....
<button
type="submit"
class="btn btn-primary"
:disabled="loading ? true : false"
#click="submitForm"
>
<span
v-show="loading"
class="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
/>
<span v-show="loading"> Wait </span>
<span v-show="!loading">
Create certificate
</span>
</button>
....
</template>
<script setup>
import { storeToRefs } from "pinia";
import { useUserStore } from "#/store/UserStore";
const { loading } = storeToRefs(useUserStore());
</script>
<script>
export default {
async submitForm() {
try {
await useUserStore().createCertificate();
} catch (error) {
console.log(error);
}
},
};
</script>
This is the pinia store:
import { defineStore } from "pinia";
import forge from "node-forge";
export const useUserStore = defineStore({
id: "UserStore",
state: () => {
return {
loading: false,
};
},
actions: {
async createCertificate() {
this.loading = true;
try {
const keys = forge.pki.rsa.generateKeyPair(2048);
} catch (error) {
console.log(error);
} finally {
this.loading = false;
}
},
},
});
The problem is, that the doStuff function already runs and the loading property is still false inside the component and the spinner is very late visible.

Vue.js return data from axios

<template>
<div class="comment">
<div v-for="(comment, index) in comments" :key="index">
{{ getUser(comment.student_idx) }}
</div>
</div>
</template>
<script>
import axios from 'axios'
import server from '#/models/server'
export default {
data() {
return {
url: server,
comments: {}
}
},
props: ['idx'],
created() {
axios.get(`${this.url}/bamboo/reply?post=${this.idx}`)
.then(response => {
if (response.data.status === 200) {
this.comments = response.data.data.replies
}
})
},
methods: {
getUser (idx) {
axios.get(`${this.url}/member/student/${idx}`)
.then(response => {
if (response.data.status === 200) {
return response.data.data.member.name
}
})
}
}
}
</script>
I would like to load the comments at created and print them out using v-for.
In v-for, I would like to load the member.name from each comment
But {{ getUser(comment.student_idx) }} is undefined.
I don't know how to return data from axios
Help me please!!
Your method should not be async for stable run code. My recomendation is next code:
<template>
<div class="comment">
<div v-for="(comment, index) in comments" :key="index">
{{ comments['user'] }}
</div>
</div>
</template>
<script>
import axios from 'axios'
import server from '#/models/server'
export default {
data() {
return {
url: server,
comments: []
}
},
props: ['idx'],
created() {
axios.get(`${this.url}/bamboo/reply?post=${this.idx}`)
.then(response => {
if (response.data.status === 200) {
this.comments = response.data.data.replies;
if(this.comments)
for(let comment of this.comments){
this.getUser(comment, comment.student_idx);
}
}
})
},
methods: {
getUser (comment, idx) {
axios.get(`${this.url}/member/student/${idx}`)
.then(response => {
if (response.data.status === 200) {
this.$set(comment, 'user', response.data.data.member.name);
}
})
}
}
}
</script>

Using HTML datalist element with VueJS? Can't use hyperlinks?

I am trying to use HTML's datalist [https://www.w3schools.com/tags/tag_datalist.asp] element rather than an autocompletion library. I tried to wrap an a href element around the post.title.
Unfortunately, it looks like this is not possible with the datalist's option element?
Here's my template:
<input v-model='post' type='text' list='posts'>
<datalist id='posts'>
<option v-for='post in posts' :key='post.id'>
<a :href='url + `${post.id}`'>{{post.title}}</a>
</option>
</datalist>
Script:
import axios from "axios";
export default {
name: "SearchBar",
data() {
return {
post: "",
posts: [],
url: "https://jsonplaceholder.typicode.com/posts/",
//placeholder: "Search or jump to item"
};
},
created() {
this.getPosts();
},
methods: {
getPosts() {
axios
.get("https://jsonplaceholder.typicode.com/posts")
.then(response => {
console.log(response);
this.posts = response.data;
})
.catch(error => {
console.log(error);
});
}
}
};
Anyone got some workarounds for this? Thank you
friend.
if you want to check.
regards!
Here's a link!
new Vue({
el: "#app",
data() {
return {
posts: []
}
},
created() {
this.getPosts()
},
methods: {
getPosts() {
axios
.get("https://jsonplaceholder.typicode.com/posts")
.then(response => {
console.log(response);
this.posts = response.data;
})
.catch(error => {
console.log(error);
});
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input list="posts" name="posts">
<datalist id="posts">
<option v-for="post in posts" :key="post.id" :value="post.title">
{{ post.title }}
</option>
</datalist>
</div>

Cannot read property 'list' of null - VueJS

Im creating a Notification component using Vuex to store data API and called it in components but I have some issues
Component.vue
<template>
<div class="notification_check">
<div class="header">
<span>Notifications </span>
<span>(1)</span>
</div>
</div>
<ul v-for="notification in $store.state.notification.notifications.list" :key="notification.id">
{{notification.id}}
</ul>
</template>
<script>
export default {
data: function () {
return {
config: {
'headers': {
'Authorization': 'JWT ' + this.$store.state.token
}
},
notifications: this.$store.state.notification.notifications.list
}
},
created: function () {
this.getNotification()
},
methods: {
getNotification: function () {
this.$store.dispatch('getNotification', this.config)
}
}
}
</script>
This is Action Commit:
getNotification ({commit}, config) {
api.get(`/notifications/`, config)
.then(response => {
commit('GET_NOTIFICATION', response.data)
})
},
This is my data API which stored in Vuex Store. Please take a look:
Error occurs:
Cannot read property 'list' of null

Can't display data in a component

I have request that returns json data...and i'm trying to display that data in vue component,but it doesn't work. In console.log is everything ok..json is something like:
[{"id":1,"body":"Hello, this is my first notification","..bla bla
here is my code
<template>
<div class="notification-container">
<p>{{ notification }}</p>
</div>
</template>
<script>
export default {
data() {
return {
notification: '',
}
},
mounted() {
axios.get('/notifications').then((response) => {
this.notification = response.data[0].body;
console.log(this.notification);
});
}
}
</script>
Try something like this :
<template>
<div class="notification-container">
<p>{{ notification /* OR this.notification[0].body */ }}</p>
</div>
</template>
<script>
export default {
data() {
return {
notification: '',
}
},
methods:{
showMsg(){
axios.get('/notifications').then( response => {
console.log(response);
this.notification = response.data[0].body;
/* OR this.notification = response; */
console.log(this.notification);
}).catch(e => {
console.log(e)
});
}
},
created() { // or mounted()
this.showMsg();
}
}
</script>