How to update data() in vue.draggable - vue.js

I know this may be basic stuff... but I cannot get my data updated when using Vue.Draggable 2.23. In the code below, the 4 lists are returned from the axios call exactly as they are now return by data(), but then, of course, with content. Somehow I keep getting "Property or method "lane0" is not defined on the instance but referenced during render." In App.vue:
<script>
import draggable from "vuedraggable";
import axios from "axios";
export default {
name: "two-lists",
display: "Two Lists",
order: 1,
components: {
draggable
},
data() {
return {
"lane0": [],
"lane1": [],
"lane2": [],
"lane3": []
}
},
mounted () {
axios
.get('http://localhost:8000/pylims/get_sequencable_lanes/10/S4')
.then(response => (this.data= response.data))
},
methods: {
log: function(evt) {
window.console.log(evt);
}
}
}
</script>
On request, the HTML part (template in App.vue):
<template>
<div class="row">
<div class="col-3">
<h3>Draggable 1</h3>
<draggable class="list-group" :list="lane0" group="people" #change="log">
<div
class="list-group-item"
v-for="(element, index) in lane0"
:key="element.sample_name"
>
{{ element.sample_name }} {{ index }}
</div>
</draggable>
</div>
<div class="col-3">
<h3>Draggable 2</h3>
<draggable class="list-group" :list="lane1" group="people" #change="log">
<div
class="list-group-item"
v-for="(element, index) in lane1"
:key="element.sample_name"
>
{{ element.sample_name }} {{ index }}
</div>
</draggable>
</div>
<div class="col-3">
<h3>Draggable 3</h3>
<draggable class="list-group" :list="lane2" group="people" #change="log">
<div
class="list-group-item"
v-for="(element, index) in lane2"
:key="element.sample_name"
>
{{ element.sample_name }} {{ index }}
</div>
</draggable>
</div>
<br><br>
{{ lane0 }}
<br><br>
{{ lane1 }}
<br><br>
{{ lane2 }}
<br><br>
{{ lane3 }}
</div>
</template>

As Tobias G. states in the comment and is clearly explained here: https://v2.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html the problem is solved by wrapping the lanes in an object, and then updating that from within the mounted() function, like this:
data() {
return {
lanes: {
"lane0": [],
"lane1": [],
"lane2": [],
"lane3": []
}
}
},
mounted () {
axios
.get('http://localhost:8000/pylims/get_sequencable_lanes/10/S4')
.then(response => (this.lanes = response.data))
},
then using it in the HTML part like this:
<draggable class="list-group" :list="lanes.lane0" group="people" #change="log">

Related

"adding" products to cart in vue not showing up in console.log

the code:
shop.vue
<template>
<div class="shop">
<div class="products" v-for="Product in items" :key="Product.id" :Product="Product"
v-on:add-To-Cart="addToCart($event)">
<h1>{{ Product.name }}</h1> <img :src="Product.pic" width="400" /> <br>
{{ Product.description }} <br>
{{ "$" + Product.price }} <br>
<button class="addToCart" #click="$emit('add-To-Cart', Product)">Add to Cart</button>
</div>
</div>
</template>
<script>
import Product from '../db.json';
export default {
name: 'shop',
data() {
return {
items: Product
}
},
methods: {
addToCart(Product) {
this.Product=Product
console.log(this.Product)
}
}
}
</script>
when I click the add to cart button it is not logging the product to the console
how can I fix that? and implement a shopping cart to my website?
Custom events are emitted from vue components not from native html elements, the same for props, you can directly call the method addToCart from the click event handler :
<template>
<div class="shop">
<div class="products" v-for="Product in items" :key="Product.id" >
<h1>{{ Product.name }}</h1> <img :src="Product.pic" width="400" /> <br>
{{ Product.description }} <br>
{{ "$" + Product.price }} <br>
<button class="addToCart" #click="addToCart(Product)">Add to Cart</button>
</div>
</div>
</template>
<script>
import Product from '../db.json';
export default {
name: 'shop',
data() {
return {
items: Product
}
},
methods: {
addToCart(Product) {
this.items.push(Product)
console.log(this.items)
}
}
}
</script>
I have a modified the code a little bit without any stylings applied. Please check the below snippet
new Vue({
el: '#app',
data() {
return {
items: [{
name: 'aaa',
description: 'about aaa',
pic: 'https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.taste.com.au%2Frecipes%2Fchocolate-cream-biscuits%2Fee3d0934-ccca-4fdf-8827-64f2fd2737e1&psig=AOvVaw1fEqbEmoJeGS0WmrnSy6pS&ust=1668580370820000&source=images&cd=vfe&ved=0CBAQjRxqFwoTCICb2LbIr_sCFQAAAAAdAAAAABAD',
price: 12,
},
{
name: 'bbb',
description: 'about bbb',
pic: 'https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.taste.com.au%2Frecipes%2Fchocolate-cream-biscuits%2Fee3d0934-ccca-4fdf-8827-64f2fd2737e1&psig=AOvVaw1fEqbEmoJeGS0WmrnSy6pS&ust=1668580370820000&source=images&cd=vfe&ved=0CBAQjRxqFwoTCICb2LbIr_sCFQAAAAAdAAAAABAD',
price: 12,
}],
cartItems:[],
};
},
methods: {
addToCart(item) {
this.cartItems.push({...item});
},
}
});
.products {
display: flex;
justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="products" v-for="product in items" :key="product.id">
<h1>{{ product.name }}</h1> <img :src="product.pic" width="400" /> <br>
{{ product.description }} <br>
{{ "$" + product.price }} <br>
<button class="addToCart" #click="addToCart(product)">Add to Cart</button>
</div>
</div>

Cannot read property 'forEach' of undefined VueJS Firebase

I use the framework VueJS and the NoSQL Database Firebase.
Here I want to display the products' data. And particulary the images of the products stored in the Cloud Firestore in Firebase.
This is the HTML code :
<div class="col-md-4"v-for="(product, index) in products" :key="index">
<div class="card product-item">
<carousel :perPage="1">
<slide v-for="(image, index) in product.images" :key="index">
<img :src="image" class="card-img-top" alt="..." width="250px">
</slide>
</carousel>
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">{{ product.name }}</h5>
<h5 class="card-prices">{{ product.price }} €</h5>
</div>
<button class="btn btn-primary mx-3 butn" >
Add to cart
</button>
</div>
</div>
</div>
and the js script :
<script>
import {db} from '../../firebase';
export default {
name: "Productslist",
props: {
msg: String
},
data(){
return {
products: [],
}
},
firestore() {
return {
products: db.collection("products")
}
}
},
};
</script>
It displays the products data like the name and the price but not the images. I have a Cannot read property 'forEach' of undefined.
Probably one of the products have images set to undefined
product.images = undefined

Accessing Vuex data within dynamic _id.vue page - Vue/Nuxt

I want to access my user details stored in the state when visiting a dynamic (_id.vue) page. I have set the id of the page like this after using the link to the page:
data() {
return {
selectedTutor: null,
id: this.$route.params.id,
}
},
But now I need to define the selectedTutor by searching the id within the data in the vuex state. I was trying to do something like this:
created() {
this.selectedTutor = this.$store.state.tutors.find((tutor) => tutor.id === this.id)
},
But everything stays undefined. So when id equals to the id within the object, that object needs to be set as selectedTutor so I can access all the necessary data to be displayed on the page.
Here you can see the Vuex state
EDIT
_id.vue page
<template>
<div>
<section>
<div>
<h3>
{{ id }}
</h3>
</div>
</section>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'TutorPage',
/* eslint-disable vue/require-prop-types */
layout: 'app',
props: ['id'],
middleware: 'auth',
data() {
return {
selectedTutor: null,
}
},
computed: {
...mapState(['tutors']),
},
created() {
this.selectedTutor = this.$store.state.tutors.find(
(tutor) => tutor.id === this.id
)
},
}
</script>
MainResult Page
<base-grid>
<ul id="tutors" class="grid grid-cols-2 gap-6">
<tutor-item
v-for="tutor in tutors"
:id="tutor.id"
:key="tutor.id"
:name="tutor.attributes.name"
:rate="student.hourlyRate"
:subject="student.subject"
:description="student.biography"
:profile-image="student.imageUrl"
:image-alt="student.imageAlt"
:age="student.age"
:rating="student.rating"
:total-reviews="student.reviewCount"
class="overflow-hidden bg-white border rounded-lg shadow-md"
>
</tutor-item>
</ul>
</base-grid>
Tutor Item (the resultcard)
<template>
<div>
<li>
<div class="flex">
<div class="w-2/3">
<img
class="flex-shrink-0 object-cover w-full h-64 mx-auto bg-gray-200"
:src="profileImage"
:alt="imageAlt"
/>
</div>
<div class="p-6">
<div
class="text-xs font-semibold leading-snug tracking-wide text-gray-500 uppercase"
>
{{ subject }} • {{ age }} jaar
</div>
<NuxtLink :to="'/tutors/' + id">
<h4 class="text-lg font-semibold leading-5 tracking-wide">
{{ name }}
</h4>
</NuxtLink>
<div class="mt-2">
{{ rate }}€
<span class="text-sm text-gray-600">per uur</span>
</div>
<div class="mt-2">
<span class="font-semibold text-light-blue-800"
>{{ rating }}/5 sterren</span
>
<span class="text-sm text-gray-600 truncate">
(na {{ totalReviews }} reviews)
</span>
</div>
<div class="mt-2">{{ description }}</div>
<div>
<div class="mt-4 text-sm font-semibold text-gray-600">
<span>MA</span>
<span
class="inline-block leading-7 text-center text-gray-100 bg-yellow-400 bg-opacity-50 w-7 h-7 rounded-xl"
>DI</span
>
<span>WO</span>
<span
class="inline-block leading-7 text-center text-gray-100 bg-yellow-400 bg-opacity-50 w-7 h-7 rounded-xl"
>DO</span
>
<span
class="inline-block leading-7 text-center text-gray-100 bg-yellow-400 bg-opacity-50 w-7 h-7 rounded-xl"
>VR</span
>
<span>ZA</span>
<span>ZO</span>
</div>
</div>
</div>
</div>
</li>
</div>
</template>
<script>
export default {
/* eslint-disable vue/require-prop-types */
name: 'TutorItem',
props: [
'id',
'firstName',
'lastName',
'name',
'rate',
'subject',
'age',
'rating',
'totalReviews',
'description',
'profileImage',
'imageAlt',
],
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
},
tutorsDetailsLink() {
return this.$route.path + '/' + this.id
},
},
}
</script>
<style></style>
EDIT
Whoops, what a mistake. It was returning the id as a string but I needed a number. This is why it returned undefined. It is solved now! Thanks

Prop value doesn't pass to child component, can't figure out why

In my parent component I'm calling my child compoment "DotsNavigation" this way:
<template>
<div>
<dots-navigation :steps="steps" />
</div>
</template>
<script>
import DotsNavigation from "#/components/dashboard/dots-navigation"
export default {
components: {
DotsNavigation
},
data: function() {
return {
steps: [
{
title: "title1",
path: "path1"
},
{
title: "title2",
path: "path2"
},
...
]
}
}
}
</script>
And my child component "DotsNavigation" looks like this:
<template>
<nav>
<div v-for="(step, key) in steps">
<router-link
:key="`dot-${key}`"
:to="`/dashboard/${step.path}`"
>
<div>
{{ key + 1 }}
</div>
<div>
{{ step.title }}
</div>
</router-link>
<div
:key="`line-${key}`"
v-if="key !== steps.length - 1"
></div>
</div>
</nav>
</template>
<script>
export default {
props: {
steps: {
type: Array,
default: () => []
}
}
}
</script>
In my child compoment, "steps" is empty. I can't figure out why this is so. Any idea?
Try not using template element in template.
In your DotsNavigation replace inner template with div and see if it works:
<template>
<nav>
<div v-for="(step, key) in steps" :key="`div-${key}`">
<router-link
:key="`dot-${key}`"
:to="`/dashboard/${step.path}`"
>
<div>
{{ key + 1 }}
</div>
<div>
{{ step.title }}
</div>
</router-link>
<div
:key="`line-${key}`"
v-if="key !== steps.length - 1"
></div>
</div>
</nav>
</template>

Pagiantion with server table is not working on vue js

I am creating a table using a ServerTable from 'vue-tables-2' to render a the data with axios and create a pagination, but the problem in the pagination the table show all the records together in the first page
I tried to fixe it but i didn't find any solution
Here you can find the component that i am using to create that table and the pagination
<template>
<div class="mt-5">
<div class="card-header purple-background bord-top-lr-5">
<h4 class="title-align font-montserrat text-light white-text-color">
{{ items.count + ' results found' }}
</h4>
</div>
<div class="card-body white-bg">
<div class="grid-x grid-padding-x m-2 border-0">
<div class="border-0 mb-2">
<v-server-table
url="/companies/search"
:columns="columns"
:options="options"
class="table-header"
>
<div slot="company_name" class="m-3" slot-scope="props">
<h5 class="title-align font-montserrat" style="color: #5b2557">
<a :href="props.row.url" :title="props.row.name">
{{ props.row.name }}
</a>
({{ $t('labels.frontend.companies.demontage') }})
</h5>
<div class="row">
<div class="col">
<p
class="gray-text-color font-montserrat-thin font-weight-bold"
>
{{ props.row.address.street }}
{{ props.row.address.building_nr }},
{{ props.row.address.postal }},
{{ props.row.address.city }}, {{ props.row.address.state }},
{{ props.row.address.country }}
</p>
</div>
<div class="col ml-lg-5">
<p
class="font-montserrat-thin blue-light-color font-weight-bold"
>
T. {{ props.row.address.phone }}<br />
<a
:href="props.row.website"
target="_blank"
:title="props.row.name"
class="gray-text-color"
>
{{ $t('labels.frontend.companies.goTo') }}
</a>
</p>
</div>
<div class="col ml-lg-5">
<a
class="font-montserrat-regular"
href="#"
style="color: #74aee0"
>
{{ $t('labels.frontend.companies.moreInfo') }} »
</a>
</div>
</div>
<button
class="mb-3 blue-light-bg btn bord-rad-5 white-text-color font-montserrat-regular"
href="#"
>
{{ $t('labels.frontend.companies.stock') }}
</button>
<br />
</div>
</v-server-table>
</div>
</div>
</div>
</div>
</template>
<script>
import Vue from 'vue'
import { ServerTable } from 'vue-tables-2'
Vue.use(ServerTable, {}, false, 'bootstrap4', 'default')
export default {
name: 'SearchCompaniesTable',
props: {
companyName: {
type: String,
required: false,
default: () => ''
}
},
data() {
return {
total: 0,
items: [],
columns: ['company_name'],
options: {
headings: {
remote_id: 'Document'
},
highlightMatches: true,
pagination: {
chunk: 10,
edge: true,
dropdown: false,
nav: 'fixed'
},
perPage: 10,
perPageValues: [10],
preserveState: true,
sortable: ['company_name'],
filterable: ['company_name'],
skin: 'table-bordered table-hover'
},
page: 1
}
},
computed: {
rows() {
return Object.keys(this.items).length
}
},
mounted() {
axios.get('/companies/search').then(response => {
this.items = response.data
})
}
}
Could you please check what mistake did i make?