Can't get ID to do delete method (VueX,VueJS) - api

I follow this guy to do my task:"Call an API to delete items"
https://www.youtube.com/watch?v=cjRst4qduzM&t=967s, start at 12:35.
According this guy said, If you wanna implement delete method there are 2 steps: Firstly, you delete items from state by get ID then use filter method to filter the id you selected.(but when you reload page item still available).Secondly, you call an api to server to delete item in server.
I get in stuck in step one, I can't get ID to delete though before I can select ID to choose company.
This is my component
<div>
<v-data-table
v-model="selected"
:search="search"
:headers="headers"
:items="items"
show-select
hide-default-footer
disable-pagination
class="elevation-1"
>
<template v-slot:item.actions="{ item }">
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<v-btn class="ma-2" v-bind="attrs" v-on="on" icon>
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item #click="editCompany(item)">
<span>Edit company</span></v-list-item
>
<v-list-item #click="deleteCompany()">
<span style="color: #e12d39"> Delete company</span>
</v-list-item>
</v-list>
</v-menu>
</template>
</v-data-table>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
props: {
items: {
type: Array,
},
search: { type: String },
},
data() {
return {
headers: [
{ text: "Name", align: "start", value: "name" },
{ text: "Phone Number", value: "phoneNumber" },
{ text: "Website", value: "website" },
{ text: "Address", value: "address" },
{ text: "Currency", value: "currency" },
{ text: "Image Name", value: "imageName" },
{ text: "Actions", value: "actions", sortable: false },
],
};
},
computed: {
...mapGetters({ deletedCompany: "companies/deletedCompany" }),
},
methods: {
deleteCompany(delID) {
console.log("dispatch:", delID);
this.$store.dispatch("companies/deleteCompany", delID);
},
},
};
</script>
and this is my store
import NProgress from "nprogress";
export const namespaced = true;
import Vue from "vue";
import Vuex from "vuex";
import { create } from "#/http/companies";
import VueToast from "vue-toast-notification";
import "vue-toast-notification/dist/theme-sugar.css";
import { getCompanies } from "#/http/companies";
// import { deleteCompanies } from "#/http/companies";
Vue.use(Vuex);
Vue.use(VueToast);
export const state = {
companies: [],
selectedCompanyId: "",
};
export const getters = {
allCompanies: (state) => state.companies,
selectedCompanyId: (state) => state.selectedCompanyId,
deletedCompanyId: (state) => state.deletedCompanyId,
selectedCompany: (state) => state.companies.find((c) => c.id === state.selectedCompanyId),
deletedCompany: (state) => state.companies.filter((c) => c.id != state.deletedCompanyId)
};
export const mutations = {
GET_COMPANIES(state, companies) {
state.companies = companies;
},
DELETE_COMPANIES(state, deletedCompanyId) {
console.log("mutations:", deletedCompanyId)
state.deletedCompanyId = deletedCompanyId;
},
SET_SELECTED_COMPANY_ID(state, selectedCompanyId) {
console.log(selectedCompanyId)
state.selectedCompanyId = selectedCompanyId
},
STORE_ID(state, payload) {
state.routeId = payload;
},
};
export const actions = {
storeID({ commit }, payload) {
commit("STORE_ID", payload);
},
getCompanies({ commit }) {
return getCompanies(NProgress.start()).then((response) => {
commit("GET_COMPANIES", response.data);
NProgress.done();
});
},
selectCompany({ commit }, companyId) {
commit("SET_SELECTED_COMPANY_ID", companyId, NProgress.start());
console.log("đây là id", companyId)
NProgress.done();
},
deleteCompany({ commit }, delId) {
console.log("actions:", delId)
return commit("DELETE_COMPANIES", delId);
},
registerCompany({ commit }, companyInfor) {
return create(companyInfor)
.then(() => {
Vue.$toast.open({
message: "Create company successfully!",
type: "success",
duration: 3000,
dismissible: true,
position: "top-right",
});
})
.catch((error) => {
commit("");
Vue.$toast.open({
message: error,
type: "error",
duration: 3000,
dismissible: true,
position: "top-right",
});
});
},
};
https://www.loom.com/share/1eb12a448aca41df8e4c77cdc8931002?focus_title=1&muted=1&from_recorder=1

pass the id via the click event handler <v-list-item #click="deleteCompany(item.id)">:
methods: {
deleteCompany(delID) {
console.log("dispatch:", delID);
this.$store.dispatch("companies/deleteCompany", delID);
// or this.$store.dispatch("companies/deleteCompany", delID);
},
},

you forgot to pass parameter as item_id to function
<v-list-item #click="deleteCompany(item)">
perhaps this will do the trick

Related

Search in vuetify datatable (server side)

I'm using vuetify datatables with server side in my app.
Pagination and sorting works fine but I have problem with search input - when I write something in input, new requests dont't send to api.
I found solution with pagination.sync in options but when I try it I get an error in the console:
[BREAKING] 'pagination' has been removed, use 'options' instead. For
more information, see the upgrade guide
https://github.com/vuetifyjs/vuetify/releases/tag/v2.0.0#user-content-upgrade-guide
My code is here:
<template>
<v-container fluid>
<v-text-field
v-model="search"
append-icon="mdi-magnify"
></v-text-field>
<v-data-table
:items="usersList"
:headers="headers"
sort-by="name"
:sort-desc="false"
:options.sync="options"
:server-items-length="totalUsers"
:search="search"
:loading="loading"
loading-text="Ładowanie..."
class="elevation-0"
></v-data-table>
</v-container>
</template>
<script>
export default {
data: () => ({
totalUsers: 0,
usersList: [],
search: "",
loading: true,
options: {},
headers: [
{ text: 'Nazwa użytkownika', value: 'name' },
{ text: 'Adres e-mail', value: 'email' },
{ text: 'Opcje', value: 'actions', sortable: false },
]
}),
watch: {
options: {
handler () {
this.getUsers();
},
deep: true
},
},
mounted () {
this.getUsers();
},
methods: {
getUsers() {
this.loading = true;
userService.getAll(this.options).then(data => {
if (data.status == "success") {
this.usersList = data.items;
this.totalUsers = data.total;
} else {
console.log("Nie udało się pobrać użytkowników.");
}
this.loading = false;
});
},
}
};
</script>

Vue.js: Child Component mutates state, parent displays property as undefined

I have a parent component that lists all the tasks:
<template>
<div class="tasks-wrapper">
<div class="tasks-header">
<h4>{{ $t('client.taskListingTitle') }}</h4>
<b-button variant="custom" #click="showAddTaskModal">{{ $t('client.addTask') }}</b-button>
</div>
<b-table
striped
hover
:items="tasks"
:fields="fields"
show-empty
:empty-text="$t('common.noResultsFound')">
</b-table>
<AddTaskModal />
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import AddTaskModal from '#/components/modals/AddTaskModal'
import moment from 'moment'
export default {
name: 'TaskListing',
components: {
AddTaskModal
},
data () {
return {
tasks: [],
fields: [
{ key: 'createdOn', label: this.$t('tasks.tableFields.date'), formatter: 'formatDate' },
{ key: 'domain', label: this.$t('tasks.tableFields.task') },
{ key: 'comment', label: this.$t('tasks.tableFields.comment') },
{ key: 'status', label: this.$t('tasks.tableFields.status') }
]
}
},
computed: {
...mapGetters('users', ['user'])
},
methods: {
...mapActions('tasks', ['fetchTasks']),
...mapActions('users', ['fetchUserById']),
formatDate: function (date) {
return moment.utc(date).local().format('DD.MM.YYYY HH:mm')
},
showAddTaskModal () {
this.$bvModal.show('addTaskModal')
}
},
async mounted () {
const currUserId = this.$router.history.current.params.id
if (this.user || this.user.userId !== currUserId) {
await this.fetchUserById(currUserId)
}
if (this.user.clientNumber !== null) {
const filters = { clientReferenceNumber: { value: this.user.clientNumber } }
this.tasks = await this.fetchTasks({ filters })
}
}
}
</script>
Inside this component there is a child which adds a task modal.
<template>
<b-modal
id="addTaskModal"
:title="$t('modals.addTask.title')"
hide-footer
#show="resetModal"
#hidden="resetModal"
>
<form ref="form" #submit.stop.prevent="handleSubmit">
<b-form-group
:invalid-feedback="$t('modals.requiredFields')">
<b-form-select
id="task-type-select"
:options="taskTypesOptions"
:state="taskTypeState"
v-model="taskType"
required
></b-form-select>
<b-form-textarea
id="add-task-input"
:placeholder="$t('modals.enterComment')"
rows="3"
max-rows="6"
v-model="comment"
:state="commentState"
required />
</b-form-group>
<b-button-group class="float-right">
<b-button variant="danger" #click="$bvModal.hide('addTaskModal')">{{ $t('common.cancel') }}</b-button>
<b-button #click="addTask">{{ $t('modals.addTask.sendMail') }}</b-button>
</b-button-group>
</form>
</b-modal>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
export default {
name: 'AddTaskModal',
data () {
return {
comment: '',
commentState: null,
taskTypesOptions: [
{ value: null, text: this.$t('modals.addTask.taskType') },
{ value: 'OnBoarding', text: 'Onboarding' },
{ value: 'Accounts', text: 'Accounts' },
{ value: 'TopUp', text: 'Topup' },
{ value: 'Overdraft', text: 'Overdraft' },
{ value: 'Aml', text: 'Aml' },
{ value: 'Transfers', text: 'Transfers' },
{ value: 'Consultation', text: 'Consultation' },
{ value: 'TechnicalSupport', text: 'TechnicalSupport' },
{ value: 'UnblockPin', text: 'UnblockPin' },
{ value: 'Other', text: 'Other' }
],
taskType: null,
taskTypeState: null
}
},
computed: {
...mapGetters('users', ['user']),
...mapGetters('tasks', ['tasks'])
},
methods: {
...mapActions('tasks', ['addNewTask', 'fetchTasks']),
...mapActions('users', ['fetchUserById']),
async addTask (bvModalEvt) {
bvModalEvt.preventDefault()
if (!this.checkFormValidity()) { return }
const currUserId = this.$router.history.current.params.id
if (this.user || this.user.userId !== currUserId) {
await this.fetchUserById(currUserId)
}
const data = {
clientPhone: this.user.phoneNumber,
comment: this.comment,
clientReferenceNumber: this.user.clientNumber,
domain: this.taskType
}
await this.addNewTask(data)
if (this.user.clientNumber !== null) {
const filters = { clientReferenceNumber: { value: this.user.clientNumber } }
this.tasks = await this.fetchTasks({ filters })
// this.tasks may be useless here
}
console.log(this.tasks)
this.$nextTick(() => { this.$bvModal.hide('addTaskModal') })
},
checkFormValidity () {
const valid = this.$refs.form.checkValidity()
this.commentState = valid
this.taskTypeState = valid
return valid
},
resetModal () {
this.comment = ''
this.commentState = null
this.taskTypeState = null
}
}
}
</script>
When I add a task I call getalltasks to mutate the store so all the tasks are added. Then I want to render them. They are rendered but the property createdOn on the last task is InvalidDate and when I console log it is undefined.
The reason I need to call gettasks again in the modal is that the response on adding a task does not return the property createdOn. I do not want to set it on the front-end, I want to get it from the database.
I logged the store and all the tasks are added to the store.
Why is my parent component not rendering this particular createdOn property?
If I refresh the page everything is rendering fine.
If you add anything into a list of items that are displayed by v-for, you have to set a unique key. Based on your explanation, I assume that your key is the index and when you add a new item, you mess with the current indexes. Keys must be unique and unmutateable. What you need to do is to create a unique id for each element.
{
id: Math.floor(Math.random() * 10000000)
}
When you create a new task, use the same code to generate a new id, and use id as key. If this doesn't help, share your d-table and related vuex code too.

Display Recipes in the Page

This is a project in order to display recipes and perform many operations on these recipes such as adding, deleting and modifying, but here I want to display the recipes and to view the recipes I wrote the following code, but the recipes were never displayed in the browser.
How can I solve this problem?
This file is for viewing recipes.
Recipes.vue:
<template>
<v-container>
<v-layout
row
wrap
v-for="recipe in Recipes"
:key="recipe.id"
class="mb-2"
>
<v-flex xs12 sm10 md8 offset-sm1 offset-md2>
<v-card class="grey lighten-4 pl-3 ">
<v-container fluid>
<v-layout row>
<v-flex xs5 sm4 md3>
<v-img height="180px" :src="recipe.imageUrl"></v-img>
</v-flex>
<v-flex xs7 sm8 md9>
<v-card-title primary-title>
<div>
<h5 class="color mb-0">{{ recipe.title }}</h5>
<div>
{{ recipe.description }}
</div>
</div>
</v-card-title>
<v-card-actions>
<v-flex>
<v-btn
text
left
:to="'/recipe/' + recipe.id"
class="green darken-1 btn-style"
>
View Recipe
</v-btn>
</v-flex>
<v-flex xs5 sm4 md2>
<v-btn class="deleteColorIcon">
<v-icon
left
class=" pl-4"
#click="$store.commit('delete_recipe', recipe.id)"
>
mdi-delete
</v-icon>
<!-- </v-btn> -->
</v-btn>
</v-flex>
</v-card-actions>
</v-flex>
</v-layout>
</v-container>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import { mapGetters } from 'vuex'
import { mapActions } from 'vuex'
export default {
actions: {
},
computed: {
...mapGetters([
//Here we put Getter
'loadedRecipes',
]),
Recipes() {
console.log('Hi I am i Recipe Component')
return this.$store.dispatch('loadedRecipes')
}
},
methods: {
...mapActions([
'createRecipe'
])
},
createRecipe() {
console.log('Hi I am in Create Recipe Component')
this.$store.dispatch('createRecipe');
},
};
</script>
<style scoped>
.color {
color: #43a047;
}
.btn-style {
color: #fafafa;
}
.deleteColorIcon {
color: #e53935;
}
</style>
And this file is for creating several functions that we want to use in other components.
store.js:
import image1 from "../../assets/img/image1.jpg";
import image2 from "../../assets/img/image2.jpg";
import image3 from "../../assets/img/image3.jpg";
import image4 from "../../assets/img/image4.jpg";
const state = {
loadedingredients: [
{ id: "1", Name: "Sugar", Quantity: "5kg" },
{ id: "2", Name: "Sugar", Quantity: "5kg" },
{ id: "3", Name: "Sugar", Quantity: "5kg" },
],
loadedRecipes: [
{
imageUrl: image3,
id: "3",
title: "Homemade Burger",
description:
"Small plates, salads & sandwiches - an intimate setting with 12 indoor seats plus patio
seating..",
// loadedingredients
},
{
imageUrl: image1,
id: "1",
title: "Cake",
description:
"Small plates, salads & sandwiches - an intimate setting with 12 indoor seats plus patio
seating..",
// loadedingredients
},
{
imageUrl: image4,
id: "4",
title: "Salad",
description:
"Small plates, salads & sandwiches - an intimate setting with 12 indoor seats plus patio
seating..",
// loadedingredients
},
{
imageUrl: image2,
id: "2",
title: "Kabseh",
description:
"Small plates, salads & sandwiches - an intimate setting with 12 indoor seats plus patio
seating.",
// loadedingredients
},
],
user: [{ name: "Hiba", email: "Hiba69#gmail.com", password: "123442321325" }],
loading: false,
};
const mutations= {
createRecipe(state, payload) {
// Vue.set(state, 'loadedRecipes', [...state.loadedRecipes, payload])
// console.log('Recipe to adad recipe.js',payload)
state.loadedRecipes.push(payload.recipeData);
},
createIngredients(state, payload) {
// Vue.set(state, 'loadedRecipes', [...state.loadedRecipes, payload])
state.loadedingredients.push(payload.ingredientData);
},
delete_recipe(state, id) {
let index = state.loadedRecipes.findIndex((recipe) => recipe.id == id);
state.loadedRecipes.splice(index, 1);
console.log("Deleted Successfully");
},
delete_ingredient(state, id) {
let index = state.loadedingredients.findIndex(
(ingredient) => ingredient.id == id
);
state.loadedingredients.splice(index, 1);
console.log("Deleted Successfully");
},
updateRecipe(state, payload) {
const recipe = state.loadedRecipes.find((recipe) => {
return recipe.id == payload.id;
});
if (payload.title) {
recipe.title = payload.title;
}
if (payload.description) {
recipe.description = payload.description;
}
},
updateingredient(state,payload) {
const ingredient = state.loadedingredients.find((ingredient)=>{
return ingredient.id == payload.id;
});
if(payload.ingredientsQuantity){
ingredient.ingredientsQuantity=payload.ingredientsQuantity
}
},
setLoading(state, payload) {
state.loading = payload;
}
}
const actions = {
createRecipe:({commit},payload)=>{
commit('createRecipe',payload)
},
delete_recipe:({commit})=>{
commit('delete_recipe')
},
updateRecipeData({ commit }, payload) {
// commit('setLoading',true)
const updateObj = {};
if (payload.title) {
updateObj.title == payload.title;
}
if (payload.description) {
updateObj.description == payload.description;
}
commit("updateRecipe", payload);
localStorage.setItem("updateRecipe", this.loadedRecipes);
},
updateIngredientData({ commit }, payload) {
// commit('setLoading',true)
const updateObj = {};
if (payload.ingredientsQuantity) {
updateObj.ingredientsQuantity == payload.ingredientsQuantity;
}
commit("updateingredient", payload);
localStorage.setItem("updateingredient", this.loadedingredients);
}
};
const getters = {
loadedRecipes: (state) => {
return state.loadedRecipes
.sort((RecipeA, RecipeB) => {
return RecipeA.id > RecipeB.id;
})
.map((aRec) => {
aRec["ingredients"] = [...state.loadedingredients];
return aRec;
});
},
featuredRecipes: (getters) => {
return getters.loadedRecipes.slice(0, 5);
},
loadedRecipe: (state) => {
return (recipeId) => {
return state.loadedRecipes.find((recipe) => {
return recipe.id === recipeId;
});
};
}
};
export default{
state,
mutations,
actions,
getters
}
First thing I can see is that it should be this.$store.state.loadedRecipes instead of this.$store.dispatch("loadedRecipes") when you load the elements from the store.
I also think you might be missing store inside the Vue instance and or the creation of the actual store.
The store should be imported like this in app.js, main.js or index.js like so:
import store from './store'
new Vue({
store,
...
})
If you don't have a index.js inside your store folder you probably haven't created the actual store:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state,
mutations,
actions,
getters
})
Read more here about the store in Vuex.
Here is a working demo of your code.
Note that I have only changed the necessary to view the items in the store. There might be other bugs.

undefined Object when i want to dispaly the Recipes

This is a project in order to display the recipes and perform many operations on these recipes such as deleting, adding and modifying the same as for presenting recipes
But when viewing the recipes I have many problems, including:
[Vue warn]: Error in render: "TypeError: Cannot read
property 'title' of undefined"
TypeError: Cannot read property 'title' of undefined
How can i solve the Problem?
Through this file, the recipes are presented in addition to calling the functions in the store.
Recipe:
<template>
<v-container>
<v-layout row wrap v-if="loading">
<v-flex xs12 class="text-xs-center">
<v-progress-circular
indeterminate
class="primary--text"
:width="7"
:size="70"
>
</v-progress-circular>
</v-flex>
</v-layout>
<v-layout row wrap v-else>
<v-flex x12>
<v-card>
<!-- <v-card-title> -->
<v-card-text>
<h4 class="btn-style mt-4 mb-4 font">
{{ recipe.title }}
</h4>
<v-spacer></v-spacer>
<app-edit-recipe-details :recipe="recipe"></app-edit-recipe-details>
<v-img height="530px" :src="recipe.imageUrl" class="mb-4"></v-img>
<div class="btn-style mb-6">
{{ recipe.description }}
</div>
<div v-for="ing in recipe.ingredients" :key="ing.id">
{{ ing.Name }} {{ ing.Quantity }}
<v-btn class="green darken-1 color mb-5 ml-4 mr-4 pl-50">
<v-icon class="green darken-1 btn-style">mdi-plus</v-icon>
</v-btn>
</div>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import { mapGetters } from "vuex";
export default {
props: ["id"],
computed: {
...mapGetters([
//Here we put Getter
'loadedRecipe',
'loadedingredient',
'loading'
]),
recipe() {
const loadedRecipe = this.$store.dispatch('loadedRecipe',this.id);
console.log("We loaded a recipe with value : ", loadedRecipe);
return loadedRecipe;
}
}
};
</script>
<style scoped>
.btn-style {
color: #43a047;
}
.color {
color: #fafafa;
}
.deleteColorIcon {
color: #e53935;
}
.font {
font-size: 30px;
}
</style>
And through this file, many of the necessary functions are performed in other components.
store.js:
import image1 from "../../assets/img/image1.jpg";
import image2 from "../../assets/img/image2.jpg";
import image3 from "../../assets/img/image3.jpg";
import image4 from "../../assets/img/image4.jpg";
const state = {
loadedingredients: [
{ id: "1", Name: "Sugar", Quantity: "5kg" },
{ id: "2", Name: "Sugar", Quantity: "5kg" },
{ id: "3", Name: "Sugar", Quantity: "5kg" },
],
loadedRecipes: [
{
imageUrl: image3,
id: "3",
title: "Homemade Burger",
description:
"Small plates, salads & sandwiches - an intimate setting with 12 indoor seats plus patio"
// loadedingredients
},
{
imageUrl: image1,
id: "1",
title: "Cake",
description:
"Small plates, salads & sandwiches - an intimate setting with 12 indoor seats plus patio"
// loadedingredients
},
{
imageUrl: image4,
id: "4",
title: "Salad",
description:
"Small plates, salads & sandwiches - an intimate setting with 12 indoor seats plus patio"
// loadedingredients
},
{
imageUrl: image2,
id: "2",
title: "Kabseh",
description:
"Small plates, salads & sandwiches - an intimate setting with 12 indoor seats plus patio"
// loadedingredients
},
],
user: [{ name: "Hiba", email: "Hiba69#gmail.com", password: "123442321325" }],
loading: false,
};
const mutations= {
createRecipe(state, payload) {
// Vue.set(state, 'loadedRecipes', [...state.loadedRecipes, payload])
// console.log('Recipe to adad recipe.js',payload)
state.loadedRecipes.push(payload.recipeData);
},
createIngredients(state, payload) {
// Vue.set(state, 'loadedRecipes', [...state.loadedRecipes, payload])
state.loadedingredients.push(payload);
},
delete_recipe(state, id) {
let index = state.loadedRecipes.findIndex((recipe) => recipe.id == id);
state.loadedRecipes.splice(index, 1);
console.log("Deleted Successfully");
},
delete_ingredient(state, id) {
let index = state.loadedingredients.findIndex(
(ingredient) => ingredient.id == id
);
state.loadedingredients.splice(index, 1);
console.log("Deleted Successfully");
},
updateRecipe(state, payload) {
const recipe = state.loadedRecipes.find((recipe) => {
return recipe.id == payload.id;
});
if (payload.title) {
recipe.title = payload.title;
}
if (payload.description) {
recipe.description = payload.description;
}
},
updateingredient(state,payload) {
const ingredient = state.loadedingredients.find((ingredient)=>{
return ingredient.id == payload.id;
});
if(payload.ingredientsQuantity){
ingredient.ingredientsQuantity=payload.ingredientsQuantity
}
},
setLoading(state, payload) {
state.loading = payload;
}
}
const actions = {
createRecipe:({commit},payload)=>{
commit('createRecipe',payload)
},
delete_recipe:({commit})=>{
commit('delete_recipe')
},
updateRecipeData({ commit }, payload) {
// commit('setLoading',true)
const updateObj = {};
if (payload.title) {
updateObj.title == payload.title;
}
if (payload.description) {
updateObj.description == payload.description;
}
commit("updateRecipe", payload);
localStorage.setItem("updateRecipe", this.loadedRecipes);
},
updateIngredientData({ commit }, payload) {
// commit('setLoading',true)
const updateObj = {};
if (payload.ingredientsQuantity) {
updateObj.ingredientsQuantity == payload.ingredientsQuantity;
}
commit("updateingredient", payload);
localStorage.setItem("updateingredient", this.loadedingredients);
}
};
const getters = {
loadedRecipes: (state) => {
return state.loadedRecipes
.sort((RecipeA, RecipeB) => {
return RecipeA.id > RecipeB.id;
})
.map((aRec) => {
aRec["ingredients"] = [...state.loadedingredients];
return aRec;
});
},
loadedingredients: (state) => {
return state.loadedingredients.sort((ingredientA, ingredientB) => {
return ingredientA.Quantity > ingredientB.Quantity;
});
},
featuredRecipes: (getters) => {
return getters.loadedRecipes.slice(0, 5);
},
loadedRecipe: (state) => {
return (recipeId) => {
return state.loadedRecipes.find((recipe) => {
return recipe.id === recipeId;
});
};
},
loadedingredient: (state) => {
return (ingredientId) => {
return state.loadedRecipes.find((ingredient) => {
return ingredient.id === ingredientId;
});
};
}
};
export default{
state,
mutations,
actions,
getters
}
The simplest solution with your current implementation would be to replace the v-else by v-else-if="recipe !== undefined" (or using a computed method v-else-if="recipeIsLoaded") inside your v-layout.

Display Boolean on Vuetify dataTable

I made a data table with vue vuetify and I fetch my data from my api server.
In my table, everything is display except boolean.
Can you help me to see clearer
Table component
<template>
<v-data-table
:headers="headers"
:items="fixture"
:items-per-page="5"
class="elevation-10"
>
</v-data-table>
</template>
<script>
export default {
name: 'my_fixtures',
props: ['fixture'],
data () {
return {
headers: [
{ text: 'name',value: 'name'},
{ text: 'State', value: 'on' },
{ text: 'Group', value: 'group' },
{ text: 'Recipe', value: 'recipe' },
{ text: 'start', value: 'startDate' },
{ text: 'end', value: 'endDate' },
{ text: 'Action', value: 'action' },
],
items: this.fixtures
}
}
}
</script>
In the object that I receive , the key 'on' is a Boolean.
I have all display , but nothing in the 'on' column
and this is what I do with props
<template>
<v-container>
<my_fixtures v-bind:fixture="fixtures"></my_fixtures>
<router-view></router-view>
</v-container>
</template>
<script>
import my_fixtures from "./greenhouse/fixtures";
export default {
name: "my_client",
data: function (){
return {fixtures: []}
},
components: {my_fixtures},
mounted() {
http.get('fixture/client')
.then(result => {
this.fixtures = result;
})
.catch(error => {
console.error(error);
});
}
}
</script>
Process and print data using methods.
try this.
<td class="text-xs-right">{{ computedOn(props.fixture.on) }}</td>
export default {
methods: {
computedOn (value) {
return String(value)
}
}
}
UPDATE
Modifying original data due to vuetify bug
https://github.com/vuetifyjs/vuetify/issues/8554
export default {
mounted() {
http.get('fixture/client')
.then(result => {
this.fixtures = result.map(value => {
value.on = String(value.on)
})
})
.catch(error => {
console.error(error);
});
}
}