i don't know why my tables are not populated with axios, this is my DataTable template, like the documentation:
<v-data-table
:headers="headers"
:items="items"
hide-actions
class="slideInDown"
>
<template slot="items" slot-scope="props">
<td>{{ props.item.nombre }}</td>
<td class="text-xs-right">{{ props.item.calle }}</td>
<td class="text-xs-right">{{ props.item.numExterior }}</td>
<td class="text-xs-right">{{ props.item.numInterior }}</td>
<td class="text-xs-right">{{ props.item.codigoPostal }}</td>
</template>
</v-data-table>
And this is my script:
<script>
export default {
data () {
return {
items: [
{
nombre: "",
calle: "",
numExterior: "",
numInterior:"",
codigoPostal: "",
}
],
}
},
methods:{
}
created(){
axios.get('http://localhost:58209/api/GetEstaciones',
{
headers:
{
"Authorization": "Bearer "+localStorage.getItem('token')
}
}).then(response => {
this.items = response.data;
}).catch(error => {
console.log(error.response)
});
},
mounted(){
let token = localStorage.getItem('token');
if(token == null){
this.$router.push('/');
}
},
}
</script>
But the table is not populated, and when i debugging my WebAPI in Visual Studio it's working the Get method even with Postman. In my script i omit the heders[], i only show the items.
In Postman shows like this:
"calle": "AVENIDA BLA",
"numExterior": 121,
"numInterior": 2,
"codigoPostal": 123456,
"nombre": "ASDFGGHJKL"
You have to use the mounted :
chk the source code of this page ( click on ok with login you with the default demo account ... )
this example has the additional logic for server side paging and replacing the url params to the back-end , but it might help you grasp the events flow better ...
Short answer ( no error handling, no paging etc. ) :
const vm = new Vue({
el: '#app',
data: {
monthly_issues: []
},
mounted() {
// this is the url of the back-end spitting out json
axios.get("/tst_issue_tracker/select/monthly_issues")
.then(response => {this.monthly_issues = response.data.dat
})
}
})
Long answer:
mounted() {
var url_params = {}
if( window.location.toString().indexOf("?") != -1) {
window.location.search.split('?')[1].replace(/([^=&]+)=([^&]*)/g, function(m, key, value) {
url_params[decodeURIComponent(key)] = decodeURIComponent(value);
});
} else {
url_params = { as:"lbls" };
}
this.UrlParams = url_params;
axios.get((window.location.pathname).replace("/list/" , "/select/") , { params: url_params } )
.then(response => {
this.gridData = response.data.dat ;
this.pageSize = url_params['page-size'] || 10 ;
this.pageNum = url_params['page-num'] || 1 ;
var totalRSsize = response.data.met ;
var remainder = totalRSsize % this.pageSize
var toAdd = 1 // page-size 10 , total-rs-size 30 => 3 and not 4
if ( remainder == 0 ) { toAdd = 0 }
this.pagesCount = Math.floor(totalRSsize/this.pageSize ) + toAdd
})
.catch(function(error) {
document.getElementById("div_msg").innerHTML="<span id=\"spn_err_msg\">" + error.response.data.msg + '</span>'
})
}
Related
With pinia on VueJS, i use a store for my licences and a licences have a number who references to a project. The projects list with informations are in an other store.
so i make getters in the licence store to get the informations of the projet (name, entreprise...).
But, when the page loading, the value of getters don't appears, and when i go in the extension on Vuejs Web browser for seeing my stores, the values appears. And I don't understand how to use the getters in my template ... I tried but no results....
I make a video to demonstrate my problem :
https://www.youtube.com/watch?v=Er4xcQ-Mq2Y
Thanks for helping !
My viewpage :
<h1>Licences actives (de type "DEV")</h1>
<table>
<tr>
<th>Numero/Clé</th>
<th>Fin d'activation</th>
<th>type</th>
<th>Entreprise</th>
<th>N° d'Affaire<br />(Projet)</th>
<th>Projet</th>
<th>Responsable</th>
<th>Version</th>
<th>Version Soft</th>
<th>Durée restante <br />(jours)</th>
</tr>
<tr v-for="article in currentList" :key="article.numero">
<td style="color: red">{{ article.numero }}</td>
<td>{{ Date_formate(new Date(article.fin_activation)) }}</td>
<td>{{ article.type }}</td>
<td style="color: red">{{ article.entreprise }}</td>
<td>{{ article.affaire }}</td>
<td>{{ article.name }}</td>
<td>{{ article.responsable }}</td>
<td>{{ article.version }}</td>
<td>{{ article.version_soft }}</td>
<td>
{{
Math.round((new Date(article.fin_activation) - Date.now()) / 86400000)
}}
</td>
</tr>
<br />
</table>
</template>
<script setup>
import { computed, onMounted, ref } from "#vue/runtime-core";
import { useListLicences } from "../stores/licence";
import { Date_formate } from "../plugin/functions";
const useListLicences2 = useListLicences();
const currentList = computed(() => {
return useListLicences2.$state.list;
</script>
The licence store in src/stores :
import { defineStore } from "pinia";
import { useListProjets } from "./projets";
const entreprises = useListEntreprises();
const projets = useListProjets();
export const useListLicences = defineStore({
id: "licences",
state: () => ({
list: [],
}),
persist: true,
getters: {
getList: (state) => state.list,
getName: (state) => //pour afficher Projet dans le tableau
state.list.map((licence) => {
projets.list.map((projet) => {
if (licence.projet_affaire == projet.affaire) {
return licence.name = projet.projetNom;
}
});
}),
getResponsable: (state) => //pour afficher Responsable
state.list.map((licence) => {
projets.list.map((projet) => {
if (licence.projet_affaire == projet.affaire) {
return licence.responsable = projet.userPseudo;
}
});
}),
getEntreprise: (state) => //pour afficher Entreprise
state.list.map((licence) => {
projets.list.map((projet) => {
if (licence.projet_affaire == projet.affaire) {
return licence.entreprise = projet.entrepriseNom;
}
});
}),
getAffaire: (state) => //pour afficher le Num d'affaire
state.list.map((licence) => {
projets.list.map((projet) => {
if (licence.projet_affaire == projet.affaire) {
return licence.affaire = projet.affaire;
}
});
}),
getID_Entreprise: (state) =>
state.list.map((licence) => {
entreprises.list.map((entreprise) => {
if (licence.entreprise == entreprise.entreprise_nom) {
return licence.ID_entreprise = entreprise.id;
}
});
}),
getContacts: (state) =>
state.list.map((licence) => {
projets.list.map((projet) => {
if (licence.projet_affaire == projet.affaire) {
return licence.contact1 = projet.email1;
}
});
}),
},
});
use this:
const currentList = computed(() => {
// removed: return useListLicenses2.$state.list
return useListLicences2.list;
})
$state is an unwrap object so there will be no response
I'm starting with laravel and vue.js. The following code that I am going to show is copied from another code that I have written and it works correctly. I've been looking for days where the error is but I can not find anything. I need this to work in order to continue.
I apologize for the description of the problem but I am not sure how to ask it.
Im getting this error:
I am getting the results of the query correctly. The view loads correctly but does not show the array data.
I can even access other response data:
The route:
Route::get('/oneminuteusers', 'OneMinuteUserController#index');
Component.vue:
<tbody>
<tr v-for="user in usersArray" :key="user.id">
<td v-text="user.user_name"></td>
<td v-text="user.gender"></td>
<td v-text="user.country"></td>
<td v-text="user.games_played"></td>
<td v-text="user.total_clicks"></td>
</tr>
</tbody>
<script>
export default {
data() {
return {
username: "",
country: "",
gender: "",
games_played: "",
total_clicks: "",
usersArray: [],
totalUsers: "",
criterio: "",
buscar: ""
};
},
computed: {
},
methods: {
listUsers(buscar, criterio) {
let me = this;
var url = "/oneminuteusers?buscar=" +buscar +"&criterio=" +criterio;
axios
.get(url)
.then(function(response) {
var respuesta = response.data;
me.usersArray = respuesta.users.data;
me.totalUsers = respuesta.totalusers;
console.log(me.totalUsers);
console.log(response.data);
})
.catch(function(error) {
console.log(error);
});
},
},
mounted() {
this.listUsers(this.buscar, this.criterio);
}
};
</script>
this problem can be raise for CROS.
the request need some headers for allow accessing cross-origin,
for solving the issue change your request as below:
var url = "/oneminuteusers";
data = {
buscar: buscar
criterio: criterio
}
header = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "X-CSRF-TOKEN, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Origin"
}
axios.get(url, data, header)
.then(function(response) {
var respuesta = response.data;
me.usersArray = respuesta.users.data;
me.totalUsers = respuesta.totalusers;
console.log(me.totalUsers);
console.log(response.data);
})
.catch(function(error) {
console.log(error);
});
`
I am using NuxtJs in my project, I a have list of checkboxes, on click of each checkbox I am sending an array of checkboxes to a my POST api which return data.
Here, when I check the first checkbox it returns the data. But when I check the second checkbox it does not does return the data.
I mean it only returns the data on single checkbox checked.
Its working with normal vuejs but not in nuxtjs
My Code:
<script>
import axios from "axios";
import uniq from "lodash/uniq";
export default {
async asyncData({ req, params }) {
let [storeInfo, feedsInfo] = await Promise.all([
axios.get(
process.env.apiURL +
"/stores/findOne?filter[where][store_name]" +
"=" +
params.id
),
axios.post(process.env.apiURL + "feeds/feedsByStores", {
stores: [params.id]
})
]);
return {
stores: storeInfo.data,
feeds: feedsInfo.data,
categories: uniq(feedsInfo.data.map(p => p.feed_category))
};
},
data() {
return {
checkedCategories: [],
checkedCategory: false,
selectedCategories: []
};
},
methods: {
feedsByCategories: function(categories) {
console.log(categories);
axios.post(process.env.apiURL + "feeds/feedsByCategories", {
categories: [categories]
}).then((res) => {
console.log(res);
})
},
categoryChecked: function(category, checked) {
this.display = "inline";
if (checked) {
this.selectedCategories.push(category);
console.log(this.selectedCategories);
this.feedsByCategories(this.selectedCategories);
} else if (!checked) {
const index = this.selectedCategories.indexOf(category);
this.selectedCategories.splice(index, 1);
this.feedsByCategories(this.selectedCategories);
if (this.selectedCategories == "") {
this.display = "none";
this.getFeeds();
}
}
if (!checked && this.selectedCategories.length === 0) {
this.getFeeds();
}
},
uncheckCategory: function(checkedCategory) {
this.checkedCategories = this.checkedCategories.filter(
name => name !== checkedCategory
);
const index = this.selectedCategories.indexOf(checkedCategory);
this.selectedCategories.splice(index, 1);
this.feedsByCategories(this.selectedCategories);
if (this.checkedCategories == "") {
this.display = "none";
this.getFeeds();
}
},
uncheckallCategories: function(event) {
this.checkedCategories = [];
this.display = "none";
this.search = "";
this.Search = "";
this.filteredCategories;
},
getFeeds() {
return this.feeds;
}
}
};
</script>
<template>
<v-layout>
<ul class="list-unstyled scrollbar">
<li v-for="(feedcategory, index) in categories" :key="feedcategory.id">
<input type="checkbox" name="category" #change="categoryChecked(feedcategory,$event.target.checked)"
:id="index + 1" :value="feedcategory" v-model="checkedCategories">
{{ feedcategory }}
</li>
</ul>
</v-layout>
</template>
My Typo,
I removed the brackets for my categories array and it worked:
feedsByCategories: function(categories) {
console.log(categories);
axios.post(process.env.apiURL + "feeds/feedsByCategories", {
categories: categories
}).then((res) => {
console.log(res);
})
}
I want to show from my api using pagination on a table with filtered data. When I put the function in methods, I get the data from (event-1), but I when I put the function of items in computed I don't get an array of data but an object. So, my data can't be showed. Please how can I get the data please?
<input type="text" class="form-control search ml-4 mb-4" placeholder="search" v-model="filterNameInput" :onChange="filterByName">
<b-table hover responsive="sm" :busy.sync="isBusy" :sort-by.sync="sortBy" :sort-desc.sync="sortDesc" :items="fetchPlaces" :fields="fields" :current-page="currentPage" :per-page="perPage" #row-clicked="rowClickHandler">
<template slot="created" slot-scope="data">
{{ data.item.created | moment().format("YYYY-MM-DD") }}
</template>
<template slot="updated" slot-scope="data">
{{ data.item.updated | moment().format("YYYY-MM-DD") }}
</template>
<template slot="categories" slot-scope="data">
<b-badge v-for="category in data.item.categories" :key="category.id" variant="primary">{{category.name}}</b-badge>
</template>
</b-table>
computed: {
fetchPlaces(ctx) {
let params = '?apikey=apiKey&lng=en&page=' + ctx.currentPage + '&limit=' + ctx.perPage
if (this.sortBy) {
params += '&sort=' + this.sortBy
if (this.sortDesc) {
params += '&dir=DESC'
}
}
if (this.filterStatus !== '' || this.filterNameInput !== '') {
params += '&sort=name&dir=ASC'
if (this.filterStatus !== '') {
params += '&filter[status]=like|' + this.filterStatus
}
console.log(this.filterNameInput)
if (this.filterNameInput !== '') {
params += '&filter[name]=%like%|' + this.filterNameInput
}
}
let promise = this.$http.get(apiUrl + params)
return promise.then((data) => {
let items = data.body.data
this.totalRows = data.body.totalItems
return (items || [])
})
}
}
Your computed is returning a Promise, not a value. Also, computeds (in their simple form) are like getters, they don't take arguments.
The proper place to make asynchronous computations is in watchers:
Create a computed that calculates params (which will recalculate every time a "part" of params changes).
Create a watcher for params to trigger the API call with the new params and update the data field fetchPlaces
Use fetchPlaces in the template, which will be updated asynchronously automatically when the API call returns.
Here's the suggested resulting code:
<b-table ... :items="fetchPlaces" ... >
data() {
// properties used somewhere in the code below (types may differ)
apiUrl: 'http://api.example.com',
currentPage: 1,
perPage: 1,
sortBy: 'somefield',
sortDesc: false,
filterStatus: 1,
filterNameInput: 'someinput',
totalRows: 0,
fetchPlaces: [],
},
computed: {
params() {
let params = '?apikey=apiKey&lng=en&page=' + this.currentPage + '&limit=' + this.perPage
if (this.sortBy) {
params += '&sort=' + this.sortBy
if (this.sortDesc) {
params += '&dir=DESC'
}
}
if (this.filterStatus !== '' || this.filterNameInput !== '') {
params += '&sort=name&dir=ASC'
if (this.filterStatus !== '') {
params += '&filter[status]=like|' + this.filterStatus
}
console.log(this.filterNameInput)
if (this.filterNameInput !== '') {
params += '&filter[name]=%like%|' + this.filterNameInput
}
}
return params;
}
},
watch: {
params(newParams, oldParams) {
this.updateFetchPlaces(newParams);
}
},
methods: {
updateFetchPlaces(newParams) {
this.$http.get(this.apiUrl + newParams).then((data) => {
let items = data.body.data
this.totalRows = data.body.totalItems
this.fetchPlaces = items || [];
});
}
},
created() {
this.updateFetchPlaces(this.params); // initial fetch
}
<v-select class="my-4 dropdownHashgroup" v-model="filterStatus" :onChange="statusOnChange" :options="placeStatus" label="label" placeholder="Status"></v-select>
<input type="text" class="form-control search ml-4 mb-4" placeholder="search" v-model="filterNameInput" :onChange="filterByName">
<b-table hover responsive="sm" :busy.sync="isBusy" :sort-by.sync="sortBy"
:sort-desc.sync="sortDesc" :items="fetchPlaces" :fields="fields" :current-page="currentPage" :per-page="perPage" #row-clicked="rowClickHandler">
</b-table>
import vSelect from 'vue-select'
export default {
name: 'grid-places',
data: () => {
return {
apiUrl: 'apiUrl',
apiKey: 'apiKey',
isBusy: false,
fields: [
{ key: 'name', sortable: true },
{ key: 'created', sortable: true },
{ key: 'updated', sortable: true },
{ key: 'score' },
{ key: 'categories' }
],
currentPage: 1,
perPage: 10,
totalRows: 0,
sortBy: 'name',
sortDesc: false,
placeStatus: ['DRAFT', 'PUBLISHED', 'DISABLED'],
filterStatus: 'PUBLISHED',
filterNameInput: '',
fetchPlaces: []
}
},
methods: {
updateFetchPlaces (newParams) {
this.$http.get(this.apiUrl + newParams).then((data) => {
let items = data.body.data
this.totalRows = data.body.totalItems
this.fetchPlaces = items || []
})
},
},
computed: {
params () {
let params = '?apikey=' + this.apiKey + '&lng=en&page=' + this.currentPage + '&limit=' + this.perPage
if (this.sortBy) {
params += '&sort=' + this.sortBy
if (this.sortDesc) {
params += '&dir=DESC'
}
}
if (this.filterStatus !== '' || this.filterNameInput !== '') {
params += '&sort=name&dir=ASC'
}
if (this.filterStatus !== '' && this.filterNameInput === '') {
params += '&filter[status]=like|' + this.filterStatus
}
if (this.filterNameInput !== '' && this.filterStatus === '') {
params += '&filter[name]=%like%|' + this.filterNameInput
}
return params
},
statusOnChange () {
},
filterByName () {
}
},
watch: {
params (newParams, oldParams) {
console.log('going to fetch for:', newParams)
this.$http.get(this.apiUrl + newParams).then((data) => {
let items = data.body.data
this.totalRows = data.body.totalItems
this.fetchPlaces = items || []
console.log(this.fetchPlaces)
console.log(this.currentPage)
})
}
},
created () {
this.updateFetchPlaces(this.params)
},
components: {
vSelect
}
My Html code part is here:
<input v-model="filterQuery" placeholder="Filter rules" class="form-control">
<table v-if="filteredUsers.length">
<tbody is="transition-group" name="user-list">
<tr v-for="user in filteredUsers" :key="user.id">
<td v-for="(column,index) in tableColumns">
<div class="rules">
{{ getField(user, column.field) }}
</div>
</td>
</tr>
</tbody>
</table>
<p v-if="statusMessage" class="well">
{{ statusMessage }}
</p>
And my Script part is:
export default ({
data: {
tableColumns: [{
field: 'name'
}],
rules: [],
filterQuery: '',
orderByField: 'name',
fetchError: false
},
created: function () {
this.fetchUsers()
},
methods: {
fetchUsers: function () {
var vm = this
vm.rules = []
vm.fetchError = false
fetch('http://172.26.3.44:8002/orientDbRestAPI/rules').then(function (response) {
return response.json()
}).then(function (rules) {
vm.rules = rules.result
}).catch(function () {
vm.fetchError = true
})
},
getField: function (object, field) {
return _.at(object, field)[0]
}
},
computed: {
filteredUsers: function () {
var vm = this
return _.orderBy(vm.rules.filter(function (user) {
var regex = new RegExp(vm.filterQuery, 'i')
console.log('>>>> ' + user.name + ' -- ' + vm.filterQuery)
return (regex.test(user.name))
}), vm.orderByField)
},
statusMessage: function () {
if (this.fetchError) {
return 'There was a problem fetching the rules. JSONPlaceholder might be down.'
}
if (this.rules.length) {
if (!this.filteredUsers.length) {
return 'Sorry, no matching rules were found.'
}
}
else {
return 'Loading...'
}
}
})
With the above code, the error below occurs when the button is clicked.
vue.runtime.esm.js?a427:430 [Vue warn]: Property or method
"filterQuery" is not defined on the instance but referenced during
render. Make sure to declare reactive data properties in the data
option.
In your template you use filterQuery but you haven't declare it in the data or the computed properties of your instance. You should define it like that:
export default ({
data: {
filterQuery: '',
// ...
},
// ...
})