getting data from json in order to fill a datatable - javascript

Good day developers ... I'm trying to fill a data table dynamically using information already fetched through a fetch and previously stored in a variable in my vuex instance and now called as computed property in my applets say I have this:
<script>
import { mapActions, mapGetters } from "vuex";
export default {
name: "Games",
data() {
return {
search: "",
headers:[
{text:'Game#', value:'Game#'},
{text:'Players in Game',value:'Players inGame'},
{text:'Permissions',value:'Permissions'},
{text:'Results',value:'Results'},
],
};
},
components: {
},
props: ["gameid"],
methods: {
...mapActions(["fetchingJsonEvents", "joinToGame","logOut", "createGame"]),
},
computed: {
...mapGetters(["getGamesAll", "getUserLogged"]),
getGamesAll(){
return this.$store.getters.getGamesAll.games-------->here is where the json is stored
}
},
created() {
this.fetchingJsonEvents();
}
};
</script>
and my html tag calling this computed and all else is like this:
<v-data-table :search="search" :headers="headers" v-bind:items="getGamesAll">
<template>
<tbody>
<tr v-for="(general, index) in getGamesAll.games" v-bind:key="index">
<td>Game {{general.id}}:</td>
<td>xxxxxxxx</td>
<td>xxxxxxxx</td>
</tbody>
</template>
</v-data-table>
but the table doesn't show any result , it worked with a v-simple-table, but once i try to do it in this way it doesn't....
Any advice .....thanks in advance

this is unnecessary:
getGamesAll(){
return this.$store.getters.getGamesAll.games
}
because you already have it using mapGetters:
...mapGetters(["getGamesAll", "getUserLogged"]),
if your getter getGamesAll have data then this should simply work:
<tr v-for="(general, index) in getGamesAll.games" v-bind:key="index">

Related

How can I avoid mutation prop and modify the same in other component?

I'm a new Dev VUE.JS and reading a lot too about "share/pass" data to anothers components, but I'm not getting perceive this examples useful in my component.
Table.vue - Fetch API and populate a table.
File.vue - Instance Table.vue and here I'm trying to override the component variable.
Table:
<template>
<v-simple-table class="mt-5" id="tableOs" dense >
<thead>
<tr>
<th v-for="h in headers" v-bind:key="h.value">{{h.text}}</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items" v-bind:key="item.id">
<td>{{item.id}}</td>
<td>{{item.customer}}</td>
<td>{{item.neighbor}}</td>
</tr>
</tbody>
</v-simple-table>
</template>
<script>
export default {
data (){
return{
headers: [
{ text: 'Id', value: 'id' },
{ text: 'Name', value: 'customer' },
{ text: 'Neighbor', value: 'neighbor' }
],
items: this.pitems,
}
},
props:{
'pitems': []
},
async created(){
const res = await fetch(
"http://localhost:5000/buscarx/3",
{
method:"GET"
}
);
const data = await res.json()
this.items = data
}
}
</script>
and my Files.vue
<template>
<v-container
id="dashboard"
fluid
tag="section"
>
<v-btn #click="modify()"> </btn>
<TableOS />
</v-container>
</template>
<script>
export default {
components:{
Table: () => import('./components/Table')
},
methods:{
modify(){
console.log(this.item)
}
}
}
</script>
Anyone can me help, suggest the best way to use this fetch and modify the data in the table to use a Filter for example in the future?
You can use props to pass variables from one component to another.
For example, you need to fetch your items data in the created hook inside File.vue. Save the fetched items in items array.
Then, you can pass this items array via prop to the Table.vue component.
You can modify, filter, map and perform other tasks to the items array in the File.vue. The changes will be reactive and automatically reflect in the Table.vue file.
You can also share variables between components using vuex. But, in case of variable sharing between child and parent, like in your case, you don't need this. But if the relation between components is not so simple or they are not related you have to use vuex.

Change state using Mutation VueJS?

So i have a Vuex Store setup which returns me headers and desserts. Inside my desserts i have a property setup named display which is initially false. I have a component Row which i am importing inside my parent component named Table. Row Components accepts a couple of props i.e. Name and Display. The display prop is what is returned from desserts from the vuex store. I am trying to add a mutation such that on Click of the icon in my Row component, the display.laptop can be toggled to true and false. I have setup the toggleLaptopDisplay but i keep getting cannot read property laptop of undefined.
Please look at the complete CodeSandbox.
Here is the complete code:
The Vuex Store:-
export default new Vuex.Store({
state: {
headers: [{ text: "Dessert (100g serving)", value: "name" }],
desserts: [
{ name: "Lollipop", display: { laptop: true } },
{ name: "Marshamallow", display: { laptop: false } }
]
},
getters: {
getHeaders: state => state.headers,
getDesserts: state => state.desserts
},
mutations: {
toggleLaptopDisplay(state) {
state.desserts.display.laptop = !state.desserts.display.laptop;
}
}
});
This is the Table Component:-
<template>
<v-data-table :headers="getHeaders" :items="getDesserts" hide-actions select-all item-key="name">
<template v-slot:headers="props">
<tr>
<th v-for="header in props.headers" :key="header.text">{{ header.text }}</th>
</tr>
</template>
<template v-slot:items="props">
<tr>
<Row :name="props.item.name" :display="props.item.display"/>
</tr>
</template>
</v-data-table>
</template>
<script>
import { mapGetters } from "vuex";
import Row from "./Row";
export default {
components: {
Row
},
data() {
return {};
},
computed: {
...mapGetters({
getHeaders: "getHeaders",
getDesserts: "getDesserts"
})
}
};
</script>
This is the Row component:-
<template>
<div>
{{name}}
<v-icon #click="toggleLaptopDisplay" :color="display.laptop ? 'info': '' ">smartphone</v-icon>
</div>
</template>
<script>
import { mapMutations } from "vuex";
export default {
props: {
name: String,
display: Object
},
methods: {
...mapMutations({
toggleLaptopDisplay: "toggleLaptopDisplay"
})
}
};
</script>
Any help will be appreciated. Thank you :)
Few things to achieve what you want:
In your Row.vue add a method to select appropriate element:
<v-icon #click="toggleChange" :color="display.laptop ? 'info': '' ">smartphone</v-icon>
then in methods, create a method that will pass name of the element as payload:
methods: {
toggleChange() {
this.toggleLaptopDisplay(this.name)
},
...mapMutations({
toggleLaptopDisplay: "toggleLaptopDisplay"
})
}
finally, in store.js, use the payload and mutate selected element:
mutations: {
toggleLaptopDisplay(state, payload) {
state.desserts.find(dessert => dessert.name === payload).display.laptop = !state.desserts.find(dessert => dessert.name === payload).display.laptop
}
}
Edited Example

Vue.js: draw the table with elements, calling the api for each row

I have a vue component:
<template>
<div class="tableWrapper">
<md-table
class="scheduledListJobList"
v-model="scheduledList"
>
<md-table-row :class="item.status" slot="md-table-row" slot-scope="{item}" #click="open(item)">
<md-table-cell class="nameColumn" md-label="Название задания" to="/upload" >{{ item.name}}</md-table-cell>
<md-table-cell md-label="Номер билда">{{ item.jobNumber }}</md-table-cell>
</md-table-row>
</md-table>
</div>
</template>
<script>
import { mapState } from "vuex";
import {permissionList} from "../../permission/permission";
import {Job} from "../../api";
export default {
name: "gg-jobs-list",
computed: mapState(["scheduledList"]),
mounted: function(){
this.$store.dispatch('GET_SCHEDULED_JOBS');
},
data: function () {
return {
element: null
};
},
methods: {
open(selected) {
this.$router.push({ path: '/jobs/' + selected.routeId});
},
refresh(){
Job.getJobs()
}
}
};
</script>
It has a scheduleList that has the name and id fields.
I need to output the name field to the table, and then call a method that goes to the backend, with each id field for the sheet elements, gets an object and complements the table.
Here is the method that calls the api:
refresh(){
Job.getJobs()
}
getJobs: id => getRequest(`/routes/monitoring/jobs/${id}`, null)
From this method, I should return an object with the start and end fields.
With these fields, I must add each scheduledList element to the tables.
How can I do this? thank you so much for your help.
Add another computed property as v-model directive value :
computed:{
...mapState(["scheduledList"]),
scheduledListRefreshed:{
get(){
return this.scheduledList.map(item=>{
item.jobs=Job.getJobs(item.id);
return item;
},
set(val){
}
}
template :
<template>
<div class="tableWrapper">
<md-table
class="scheduledListJobList"
v-model="scheduledListRefreshed"
>
<md-table-row :class="item.status" slot="md-table-row" slot-scope="{item}" #click="open(item)">
<md-table-cell class="nameColumn" md-label="Название задания" to="/upload" >{{ item.name}}</md-table-cell>
<md-table-cell md-label="Номер билда">{{ item.jobNumber }}</md-table-cell>
</md-table-row>
</md-table>
</div>
</template>

v-data-table in component: how to have all items selected by default?

I have a v-data-table in a component, and am using the checkboxes created by select-all to filter information in the component's parent. None of the rows start off selected. I would like all of them to be checked by default.
Things that have not worked:
in the parent's data: setting selectedItems to Array.from(this.$store.state.tableItems) by default (the item in the store isn't defined at that point)
in the mounted or created event in the child: setting selectedItems to Array.from(this.tableItems) (this produces an "avoid mutating a prop directly" error)
I feel like there is probably a way to do this with a computed property?
(There is probably also a more idiomatic way using actions or events or something? I am new to Vue.)
MyComponent.vue
<template>
<v-data-table
:value="selectedItems"
#input="$emit('update:selectedItems', $event)"
:headers="headers"
:items="tableItems"
item-key="id"
select-all
>
<template slot="items" slot-scope="props">
<td>
<v-checkbox v-model="props.selected" hide-details></v-checkbox>
</td>
<td>{{ props.item.id }}</td>
</template>
</v-data-table>
</template>
<script>
export default {
props: {
tableItems: { type: Array, },
selectedItems: { type: Array, },
},
data() {
return {
headers: [
{ text: 'ID', value: 'id', },
],
};
},
};
</script>
Parent.vue
<template>
<MyComponent :tableItems="tableItems" :selectedItems.sync="selectedItems"/>
</template>
<script>
export default {
components: {
MyComponent,
},
data() {
return {
selectedItems: [],
};
},
computed: {
tableItems() {
return this.$store.state.tableItems; // set by an axios request in beforeCreate in App.vue
},
}
};
</script>
Alright, the following did work (I was already using Vuex) but I'm hoping someone else has a more satisfying answer.
store.js
Track the selected items here. The default value of null is so that, when setting the table items after the first axios call finishes, we can set the default.
export default new Vuex.Store({
state: {
tableItems: {},
selectedItems: null,
},
mutations: {
setTableItems(state, payload) {
state.tableItems= payload;
if (state.selectedItems == null) state.selectedItems = payload;
},
setSelectedItems(state, payload) {
state.selectedItems = payload;
},
}
});
MyComponent.vue
What changed here is that I'm using the selected elements to the Vuex store as the value for the data table, and then committing a mutation on every input.
<template>
<v-data-table
:value="selectedItems"
#input="updateSelectedItems"
:headers="headers"
:items="tableItems"
item-key="id"
select-all
>
<template slot="items" slot-scope="props">
<td>
<v-checkbox v-model="props.selected" hide-details></v-checkbox>
</td>
<td>{{ props.item.id }}</td>
</template>
</v-data-table>
</template>
<script>
export default {
props: {
tableItems: { type: Array, },
},
data() {
return {
headers: [
{ text: 'ID', value: 'id', },
],
};
},
methods: {
updateSelectedItems(event) {
this.$store.commit("setSelectedItems", event);
},
},
computed: {
selectedItems() { return this.$store.state.selectedItems; },
}
};
</script>
Parent.vue
This ends up being a lot simpler; less data binding, just referencing the store.
<template>
<MyComponent :tableItems="tableItems"/>
</template>
<script>
export default {
components: {
MyComponent,
},
computed: {
tableItems() { return this.$store.state.tableItems; },
selectedItems() { return this.$store.state.selectedItems; },
}
};
</script>

How to recover data from one component to another in vue JavaScript

I have two components:
component 1: recherche
<template>
<button #click='allRecords()'>Search</button>
<table>
<thead>
<th class="center">Date</th>
<th class="center">Statut</th>
</thead>
<tbody>
<tr v-for='contact in contacts' #click="seeContactDetails(contact.data.bid)">
<td>{{ contact.date }}</td>
<td>{{ contact.data.statut }}</td>
</tr>
</tbody>
</table>
</template>
<script lang="js">
import axios from 'axios';
export default {
name: 'recherche',
components: {
},
props: [],
mounted() {
},
data() {
return {
contacts: [],
details:[],
}
},
methods: {
allRecords: function() {
axios.get(`/api/recherche/`)
.then(response => {
this.contacts = response.data.list;
})
.catch(error => {
console.log(error);
});
},
seeContactDetails: (bid) => {
window.location = `/#/detail/${bid}`;
axios.get(`/api/detail/contacts?bid=${bid}`)
.then(response => {
this.details = response.data.list;
})
.catch(error => {
console.log(error);
});
}
},
}
</script>
But I want to display the result of seeContactDetails (bid) in the detail component
Component 2: detail
<template lang="html">
<div v-for='detail in details'>
<!-- ligne -->
<div class="row">
<!-- colonne -->
<div class="col-md-2">org: {{detail.data.org}}</div>
<div class="col-md-2">num:{{detail.data.num}} </div>
</div>
</template>
<script lang="js">
export default {
name: 'detail',
props: ['recherche'],
mounted() {},
data() {
return {
details: []
}
},
methods: {
},
computed: {
}
}
</script>
In summary I want to read the resuts of an axios query, in another component, but I do not know how we do, despite the docs.
I try to put the name of the component recherche in props of detail but it does not work
The way I would recommend doing this (for most cases) is to use vuex.
These are the files I would use
vuex (store, actions, mutators, getters)
apiHandler (a utility function making the actual call)
component 1
component 2
After some action on component 1, a vuex action is triggered. Inside the vuex action the appropriate apiHandler function is invoked. Inside the vuex action the response is handled with a then(), which pushes the response into the vuex mutator. This mutation will update the getter which will update any component that is listening to the change in state.
It's a bit more complex than having the components talk directly, but it makes the architecture scalable.

Categories

Resources