I try without success to display the options of smart select. I recover the options with axios and I make a v-for to display the options but without success. I first put the function that allows me to retrieve the data in the computed hook without success then I put it in the mounted hook and I used the setvalue property of smart select without success too. Any help is welcome and I thank you in advance.
methods: {
async getTokensLists() {
const self = this;
let url = f7.store.getters.getApiUrl.value + "tokens/";
await self
.axios({
url,
method: "get",
withCredentials: false,
})
.then((response) => {
if (response.satus == 200) {
self.tokensList == response.data.data;
}
})
.catch((error) => {
console.log(error);
});
},
},
async created() {
const self = this;
// Error: Uncaught Error: Smart Select requires initialized View
self.getTokensLists();
},
computed: {
/*case 1
Error items readonly
code:
items () {
return this.tokensList
}*/
},
mounted(){
/*case 2
Error: new data not display in front
code:
this.$nextTick(() => {
this.$refs.item.f7SmartSelect.setValue(['test']);
});*/
}
Here is the template part
<f7-list-item
title="Add tokens"
smart-select
:smart-select-params="{
openIn: 'popup',
searchbar: true,
searchbarPlaceholder: 'Search token',
pageTitle: 'Add tokens',
}"
#smartselect:closed="updateSelectedtokensData"
>
<select v-model="tokensList" name="select-token" multiple>
<optgroup label="">
<option
v-for="(item, key) in tokensList"
:key="key"
:value="item.symbol"
>
{{ item.name + " (" + item.symbol + ")" }}
</option>
</optgroup>
</select>
<template #media>
<f7-icon
ios="f7:plus_circle"
aurora="f7:plus_circle"
md="material:add_circle_outline"
size="30"
></f7-icon>
</template>
</f7-list-item>
To load the async data I used the setup method and the Suspense component of view 3
radar component
...
async setup(){
const tokensList = ref(null)
await axios({
url: f7.store.getters.getApiUrl.value+"tokens/",
method: "get",
withCredentials: false,
}).then(response =>{
if (response.status == 200) {
tokensList.value = response.data.data;
}
}).catch(error =>{
console.log(error)
})
return {
tokensList
};
}...
app.vue
<!-- Radar View -->
<f7-view
id="view-radar"
:class="{ 'web-view': isDesktop }"
name="Radar"
tab
:router="false"
>
<Suspense>
<template #default>
<radar></radar>
</template>
<template #fallback>
<f7-page name="radar">
<!-- Top Navbar -->
<f7-navbar title="Radar">
<f7-nav-right>
<f7-link
icon-ios="f7:funnel_fill"
icon-aurora="f7:funnel_fill"
icon-md="material:filter_alt"
popup-open=".filter-popup"
></f7-link>
</f7-nav-right>
</f7-navbar>
<f7-block class="text-align-center" style="margin-top: 20%;"
><f7-preloader color="multi" :size="42"></f7-preloader
></f7-block>
</f7-page>
</template>
</Suspense>
</f7-view>
...
Related
My goal is to store a specific data in the localStorage when I click on a link
but log i get is either undefined or absolutely nothing.
<li v-for="(categorie, index) in categories" :key="index">
<a href="./currentCategory" #click.prevent="getCategory()">
<img class="categorie-img" :src="categorie.strCategoryThumb" >
<p>{{ categorie.strCategory }}</p>
</a>
</li>
data() {
return {
categories: []
}
},
methods: {
getAllCategories() {
axios
.get('https://www.themealdb.com/api/json/v1/1/categories.php')
.then((response) => {
console.log( response.data);
this.categories = response.data.categories;
}).catch(error => {
console.log(error);
alert("api can't be reached");
})
},
getCategory() {
localStorage.setItem('currentCategory', this.categorie.strCategory );
}
},
I am using this API https://www.themealdb.com/api/json/v1/1/categories.php
I guess this.categorie.strCategory is incorrect but i really cant figure it out
I also tried this.categories.strCategory
Try to pass category
#click.prevent="getCategory(categorie)
then save it
getCategory(cat) {
localStorage.setItem('currentCategory', cat );
}
Found the answer thanks to #Nikola Pavicevic
had to pass a category to the click event
#click.prevent="getCategory(categorie.strCategory)
and pass it to the function
getCategory(cat) {
localStorage.setItem('currentCategory', cat);
}
I have bootstrap-vue "b-table" used in my Vue page. Each row has an "view-details" button, that shows additional information about the selected row. I was looking for examples that can send request to backend when user clicks for view-details, that expands the row and shows details retrieved from backend. The "_showDetails" option from bootstrap-vue table seems limited as the examples all use the data that was already loaded along with the main tableland using this way would overload the page as my data for each row is too big.
Are there any examples or even other libs that support such functionality?
You can do this with bootstrap-vue without any problems.
Create a method that gets called when you click your "view details" button, this method will call your backend and insert the data onto your item. Once the data has been retrieved you set _showDetails to true on the item, which will open the details.
You could also open it immediately and show a loading message while the data is retrieved, that's up to you.
new Vue({
el: '#app',
created() {
// Get initial data
fetch('https://reqres.in/api/users')
.then(response => response.json())
.then(json =>
/* Map and use only some of the data for the example */
this.items = json.data
.map(user => {
return {
id: user.id,
first_name: user.first_name,
last_name: user.last_name
}
}))
},
data() {
return {
items: [],
fields: ['id', 'first_name', 'last_name', {
key: 'actions',
label: ''
}]
}
},
methods: {
toggleDetails(item) {
if (item._showDetails) { // if details are open, close them
item._showDetails = false
} else if (item.details) { // if details already exists, show the details
this.$set(item, '_showDetails', true)
} else {
fetch(`https://reqres.in/api/users/${item.id}`)
.then(response => response.json())
.then(json => {
const user = json.data;
item.details = {
email: user.email,
avatar: user.avatar
}
this.$set(item, '_showDetails', true)
})
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.5.0/dist/bootstrap-vue.min.js"></script>
<link href="https://unpkg.com/bootstrap-vue#2.5.0/dist/bootstrap-vue.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap#4.3.1/dist/css/bootstrap.min.css" rel="stylesheet" />
<div id="app">
<b-container>
<b-table :items="items" :fields="fields">
<template v-slot:cell(actions)="{ item }">
<b-btn #click="toggleDetails(item)">
Show details
</b-btn>
</template>
<template v-slot:row-details="{ item : { details: { email, avatar }}}">
<b-card>
<b-img :src="avatar" fluid></b-img>
{{ email }}
</b-card>
</template>
</b-table>
</b-container>
</div>
i need to update the follow an unfollow button after axios request
<template>
<div v-if="isnot">
<a href="#" #click.prevent="unfellow" v-if="isfollowing" >unFellow</a>
<a href="#" #click.prevent="fellow" v-else >Fellow</a>
</div>
</template>
My Methods
fellow () {
axios.post(`/#${this.follower}/follow/`)
},
unfellow () {
axios.post(`/#${this.follower}/unfollow/`)
},
}
A basic example:
fellow () {
var self = this;
axios.post(`/#${this.follower}/follow/`)
.then(function (response) {
self.isfollowing = true;
})
.catch(function (error) {
console.log( error.response.data);
});
},
Axios has a series of methods you can execute after the response arrives. In the case of a post call your structure can be something like this
axios.post(YOUR ROUTE)
.then(function (response) {
//executes after getting a successful response
// here you can change your 'isfollowing' variable accordingly
})
.catch(function (error) {
//executes after getting an error response
});
Fast way:
<template>
<div v-if="isnot">
<a href="#" #click.prevent="fellowUnfellow" v-if="isfollowing" >{{isfollowing ? "unFellow" : "Fellow"}}</a>
</div>
</template>
fellowUnfellow () {
axios.post(`/#${this.follower}/follow/`).then(function (r) {
this.isfollowing = !this.isfollowing;
})
}
I am having trouble displaying product via product component.
First in my vue.js app, I load Products via ajax like so:
var app = new Vue({
el: '#app',
data: {
products: [] // will be loaded via Ajax
},
mounted: function () {
var self = this;
ajaxGetProducts(0, self); // ajax, to fetch products
},
methods: {
getProducts: function (event) {
let groupID = Number(document.getElementById("GroupSelect").value);
ajaxGetProducts(groupID, this);
}
}
});
//Ajax call to fetch Products
function ajaxGetProducts(groupID, self) {
$.ajax({
type: "POST",
url: "/Data/GetProducts",
data: { Id: groupID },
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
dataType: "json"
, success: function (response) {
self.products = response; // Loading products into the App instance
},
error: function (jqXHR, textStatus, errorThrown) {
self.products = [];
}
}).done(function () {
});
}
Then I display those produdcts, and it works just fine:
<!-- HTML -->
<div id="app">
<div v-for="prod in products" >{{prod.Id}}</div>
</div>
Question: if I want to use a component. How do I do that?
This is how my component looks so far:
Vue.component('product', {
props: [],
template: `<div>ProdID: {{product.Id}} {{product.Qty}}</div>`,
data() {
return {
Id: "test id"
}
}
})
Example Product object has following properties:
{
Id: 1,
Qty: 5,
Title: "Nike shoes",
Price: 200,
Color: "Green"
}
And eventually I would like to use it in HTML like so:
<!-- HTML -->
<div id="app">
<!-- need to pass prod object into product component -->
<div v-for="prod in products" >
<product></product>
</div>
</div>
I know that I have to pass the object via Component properties somehow?
Passing each property 1 by 1 is not a good idea, cause this product is subject to change, so property name can change, or be added more. I think there should be a way to pass a whole Product object to Product component somehow, right?
You can pass the information into your component via the props
something like this;
Vue.component('product', {
props: ['item'],
template: `<div>ProdID: {{item.Id}} {{item.Qty}}</div>`
})
and pass it on like this;
<div id="app">
<div v-for="prod in products" :key='prod.Id'>
<product :item='prod'></product>
</div>
</div>
What about passing it as
<product v-for="prod in products" :key="prod.Id" :product="prod"></product> and in the component: props: {product:{type: Object, required: true}}?
Then in the component template you can use things like {{product.Id}}
I am using vue.js 2 with webpack template. i am new to vue.js.
i want to bind DOM after data is received in ajax call.
here in my code contains v-for in which the response html is need to bind with v-html="tHtml[index]" every time after data is received from api call.
What can be used to re-bind or refresh view/DOM as we use $scope.$apply() in angularjs.
home.vue
<template>
<div class="row" id="home">
<h3 v-if="msg"><span class="label label-warning">{{msg}}</span></h3>
</div>
<div v-for="obj in tdata">
<div v-html="tHtml[$index]"></div>
</div>
</div>
</template>
<script>
import appService from '../service'
import bus from '../service/bus'
export default {
created() {
appService.checkAuth();
console.log("service appService val: "+appService.user.authenticated);
//called after vue has been created
bus.$on('eventBusWithTopic', (data) => { //fetch event bus on ready to get data
//alert("event fetched! "+data.user_id);
console.log("event fetched! "+data.user_id);
this.searchedTopic = data.topic;
this.user_id = data.user_id;
bus.$off('eventBusWithTopic'); //un-bind event after use
//check details
})
},
data() {
return {
searchedTopic: '',
user_id: '',
tdata: {},
tHtml: []
}
},
methods: {
getdata(){
console.log("dfd "+this.user_id);
appService.getdata(this, this.user_id, this.searchedTopic).success((res) => {
//console.log(" res: "+JSON.stringify(res));
this.tdata = res.data;
if(this.tdata.length > 0){
//**GET HTML** // <<--==--==--==
for(var i=0;i<this.tdata.length;i++){
this.getTemplate(this.tdata[i].id_str);
}
}
if(res.success == 0)
this.msg = res.message;
}).error((e) => console.log("error while getting data: "+JSON.stringify(e)))
},
getTemplate(id){
this.$http.get("https://uqkcgyy8wb.execute-api..*****../user/"+id+"/getHtml", (resp) => {
//return resp.data.html;
this.tHtml[this.tHtml.length] = resp.data.html;
console.log(this.tHtml);
}).error((e) => console.log("error while getting html: "+JSON.stringify(e)))
}
}
}
</script>