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

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>

Related

Vuejs - How to get the current id in a url of an api with axios

When the client clicks on the button, I want him to block another client, so I want my id to be dynamic: http://example/user/:id.
My template:
<template>
<div class>
<div v-for="post in posts" :key="post.id">
<div>
<div>{{ post.name }}</div>
<div>{{ post.id }}</div>
<button #click='BlockUser'>Block</button>
</div>
</div>
</div>
</template>
And my script:
<script>
const axios = require('axios');
export default {
name: 'User',
data() {
return {
posts: [],
errors: [],
id: {
id: ""
},
}
},
methods: {
getData() {
axios.get(`http://example/user`)
.then(result => {
this.posts = result.data
console.log(result)
})
},
BlockUser() {
axios.get('http://example/user/blacklist/:id' + encodeURIComponent(this.id.id))
.then(response => {
console.log(response)
})
},
},
}
</script>
Initially, I set a value for the id in data id a number and it worked. But now that I put an empty string.
it returns an undefined
If your posts have user_id field inside, you can pass it to BlockUser method, and use it in the request url.
<button #click='BlockUser(post.user_id)'>Block</button>
BlockUser(user_id) {
axios.get(`http://example/user/blacklist/${user_id}`)
.then(response => {
console.log(response)
})
},

Loading component after fetch in vuejs

I'm trying to consume an API using axios.
This is my code untill now
<select>
<option v-for="value in values"> value.name </option>
</select>
// js
data(){
values: [],
},
created() {
this.getData();
},
methods: {
getData: () => {
axios.get('url')
.then(res => {
this.value = res.data.dados;
console.log(res.data.dados);
})
.catch(error => {
console.log(error);
});
}
}
The promise's console.log is working normally, but the options with data isn't rendered.
It's probably because my select component is being rendered before the 'getData()'. How can I fix it?
Just put a loading handler.
<select v-if="loaded">
<option v-for="value in values"> value.name </option>
</select>
// js
data(){
values: [],
loaded: false,
},
created() {
this.getData();
},
methods: {
getData: () => {
axios.get('url')
.then(res => {
this.value = res.data.dados;
this.loaded = true;
})
.catch(error => {
console.log(error);
this.loaded = true;
});
}
}
You've a typo on this.value, it should be this.values. If that doesn't work, use this.$forceUpdate() to force re-render component
<select>
<option v-for="value in values">{{ value.name }}</option>
</select>
// js
data(){
values: [],
},
created() {
this.getData();
},
methods: {
getData: () => {
axios.get('url')
.then(res => {
this.values = res.data.dados; // change value to values
console.log(res.data.dados);
this.$forceUpdate(); // add forceUpdate
})
.catch(error => {
console.log(error);
});
}
}

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>

Call $emit after dispatch action in Vuejs

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

VueJs, call a method from concatenated element

I would like to call a method from a concatenated checkbox.
here is my code:
methods: {
listServices(serviceId) {
axios
.get(
process.env.ROOT_API + "Service/List?Id=" + serviceId,
this.$store.getters.getTokenHeaderFormData
)
.then(response => {
response.data.forEach(el => {
this.dataset.push([
el.serviceName,
`<input type="checkbox"
onchange="${this.updateService(el.ServiceId)}">` // <-- Call UpdateService method
]);
});
})
.catch(error => {
console.log(error);
});
},
updateService(serviceId){
console.log(serviceId);
},
The onchange="${this.updateService(el.ServiceId)}" does not work. how can I do this?
The proper way to do this is to use v-for:
<template>
<ul>
<li v-for="item in dataset" :key="item[1]">
<input type="checkbox" #change="updateService(item[1])">
</li>
</ul>
</template>
<script>
export default
{
methods:
{
listServices(serviceId)
{
axios.get(
process.env.ROOT_API + "Service/List?Id=" + serviceId,
this.$store.getters.getTokenHeaderFormData
).then(response =>
{
response.data.forEach(el =>
{
this.dataset.push([
el.serviceName,
el.ServiceId
]);
});
}).catch(error =>
{
console.log(error);
});
},
updateService(serviceId)
{
console.log(serviceId);
},
}
}
</script>