not able to vue pass props to component's data - javascript

I am trying to pass the props in my component to the same component's data object. However, I am only getting null. Can anyone advise how I should approach this? It seems that my vue component is not able to get the props on initial rendering/load.
const teamInformationTemplate = {
template:
`
<div class="col-lg-6 col-md-12">
<div class="card card">
<!---->
<div class="card-header">
<h6 class="title">
TEAMS
</h6>
<br>
<select id="select_model_version" #change="get_team_information($event.target.value)" class="form-control form-control-sm form-group col-md-4">
<option v-for="team in teams" :value="team.team_id" :key="" :id="team.team_id">
{{ team.team_name }}
</option>
</select>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table tablesorter">
<thead class="text-primary">
<tr>
<th>#</th>
<th>Name</th>
</tr>
</thead>
<tbody class="">
<tr v-if="team_members!=null" v-for="(member, index) in team_members">
<td>{{index+1}}</td>
<td>{{member.firstname}}
</tr>
</tbody>
</table>
</div>
<!---->
<!---->
</div>
</div>
</div>
`,
props: ['teams', 'team_members', 'team_name'],
data() {
return {
template_teams : this.teams,
template_team_name : this.team_members,
template_team_members : this.team_name,
}
},
methods: {
get_team_information : function (team_id) {
$.post(js_local.ajaxurl, {
action: 'abcdefg',
team_id: team_id
}).done((data) => {
let parsed_data = JSON.parse(data)
}).fail(function (data) {
console.log('fail # { action : get_team_information }', data)
})
}
}
}

Try to initialize them inside the updated hook as follows:
data() {
return {
template_teams: [],
template_team_name: [],
template_team_members: [],
}
},
updated() {
this.template_teams = this.teams;
this.template_team_name = this.team_members;
this.template_team_members = this.team_name;
}

Related

Uncaught (in promise) TypeError: Cannot use 'in' operator to search for 'path' in undefined

I am a new learner. I am trying to add cart feature using vue. Here is my view name Cart.vue for the cart.
<template>
<div class="page-cart">
<div class="columns is-multiline">
<div class="column is-12">
<h1 class="title">Cart</h1>
</div>
<div class="column is-12 box">
<table class="table is-fullwidth" v-if="cartTotalLength">
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
<th></th>
</tr>
</thead>
<tbody>
<CartItem
v-for="item in cart.items"
v-bind:key="item.product.id"
v-bind:initialItem="item" />
</tbody>
</table>
<p v-else>You don't have any products in your cart...</p>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import CartItem from '#/components/CartItem.vue'
export default {
name: 'Cart',
components: {
CartItem
},
data() {
return {
cart: {
items: []
}
}
},
mounted() {
this.cart = this.$store.state.cart
},
computed: {
cartTotalLength() {
return this.cart.items.reduce((acc, curVal) => {
return acc += curVal.quantity
}, 0)
},
}
}
</script>
This is the CartItem.vue component that I used:
<template>
<tr>
<td><router-link :to="item.product.get_absolute_url">{{ item.product.name }}</router-link></td>
<td>Rs {{ item.product.price }}</td>
<td>
{{ item.quantity }}
</td>
<td>Rs {{ getItemTotal(item).toFixed(2) }}</td>
<td><button class="delete"></button></td>
</tr>
</template>
<script>
export default {
name: 'CartItem',
props: {
initialItem: Object
},
data() {
return {
item: this.initialItem
}
},
methods: {
getItemTotal(item) {
return item.quantity * item.product.price
}
},
}
</script>
I cannot see any product and the related values in the cart. I am getting this error -
Uncaught (in promise) TypeError: Cannot use 'in' operator to search for 'path' in undefined.
I am unable to find out the mistake in my code. Please help me out. When I am removing the component from the cart.vue, then the error gets eliminated. But I need that component.

sort table based on index with b-buttons (up and down)

I'm working with BootstrapVue.
I have a table where I can input rows with my b-button. After inserting different rows I want to have a - I will name it sort function.
So I want to be able to change the order with two buttons (here: Up and Down) based on their index. So the index should always be the same but the ID should switch.
Also I have - if my index is equal to zero - disabled the button because I could not be able to go "higher". This I also want on the last element..
Thanks for helping me out!
This is how it looks for better understanding:
INFO You should be able to copy paste the code and it should work.
Code of template
<template>
<div>
<b-button #click="addNewItem()">Add Input</b-button>
<h3 class="mt-5 ml-3 mb-2"><strong>Created Table</strong></h3>
<table class="table table-striped col-md-12 mt-4">
<tr>
<div class="row mt-2 mb-2">
<th class="col-md-1 ml-4">INDEX</th>
<th class="col-md-1">ID</th>
<th class="col-md-1">CHANGE #</th>
</div>
</tr>
<tr v-for="(item, index) in inputs" :key="item.id">
<div class="row mt-2 mb-2">
<td class="col-md-1 ml-4">#{{ index + 1 }}</td>
<td class="col-md-1 mr-1">{{item.id}}</td>
<td class="col-md-3">
<b-button :disabled="index == 0" size="sm mr-1">Up</b-button>
<b-button size="sm">Down</b-button>
</td>
</div>
</tr>
</table>
</div>
</template>
Code of script
<script>
export default {
data() {
return {
inputs: [{
id: 1
}],
id: 1,
}
},
methods: {
addNewItem() {
this.inputs.push({
id: this.id += 1
})
}
}
}
</script>
I think the answer is self-explanatory ..
TEMPLATE
<b-button :disabled="index == 0" #click="sortUp(index)"><b-icon icon="arrow-up"></b-icon></b-button>
<b-button :disabled="index == (inputs.length - 1)" size="sm"><b-icon icon="arrow-down" #click="sortDown(index)"></b-icon></b-button>
SCRIPT
sortUp(index) {
var element = this.inputs[index];
this.inputs.splice(index, 1);
this.inputs.splice(index-1, 0, element);
},
sortDown(index) {
var element = this.inputs[index];
this.inputs.splice(index, 1);
this.inputs.splice(index+1, 0, element);
},

How to share data between two component in vuejs with Event Bus

I am trying to implement a global event bus in order to send a variable from component A to component B.
Here is the component A code:
data () {
return {
commandes: [],
}
},
envoyer() {
this.$eventBus.$emit('commande', this.commandes);
},
Here is the component B code:
<template>
<div class="container">
<div class="row justify-content-center">
<!-- Table row -->
<div class="row">
<div class="col-12 table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Qté</th>
<th>Produit</th>
<th>Subtotal</th>
</tr>
</thead>
<tbody>
<tr v-for="(commande, index) in commandes" :key="index">
<td>{{ commande.quantite }}</td>
<td>{{ commande.produit_id }}</td>
<td>{{ commande.montant }}</td>
</tr>
</tbody>
</table>
</div>
<!-- /.col -->
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
commande: [],
}
},
methods: {
},
mounted() {
this.$eventBus.$on('commande', (commandes) => {
this.commande = commandes;
console.log(commandes);
})
}
}
</script>
I'm getting this error when component B is displayed:
[Vue warn]: Property or method "commandes" is not defined on the instance but referenced during render.
How to solve this?
In your template you are referencing commandes
<tr v-for="(commande, index) in commandes" :key="index">
but your data doesn't return it, it returns commande
data() {
return {
commande: [],
}
}
Update your data and bus listeners:
data() {
return {
commandes: [],
}
}
...
this.$eventBus.$on('commande', (commandes) => {
this.commandes = commandes;
console.log(commandes);
})

Error compiling template while trying to make email links in Vue

I am working on a small application that displays a "users" JSON in an HTML5 table. It uses Bootstrap 3 and Vue.
The code I have so far:
var app = new Vue({
el: '#app',
data () {
return {
users: null,
loading: true,
errored: false
}
},
mounted () {
axios
.get('https://jsonplaceholder.typicode.com/users')
.then(response => {
this.users = response.data
})
.catch(error => {
console.log(error)
this.errored = true
})
.finally(() => this.loading = false)
}
});
Vue.filter('lowercase', function (value) {
return value.toLowerCase();
})
<script src="https://unpkg.com/axios#0.18.0/dist/axios.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="container">
<div class="panel panel-default table-container">
<div class="panel-heading">Users</div>
<div class="panel-body">
<table class="table table-striped table-bordered" id="dataTable">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Email</th>
<th>City</th>
</tr>
</thead>
<tbody>
<tr v-for="(user, index) in users">
<td>{{index + 1}}</td>
<td>{{user.name}}</td>
<td>{{user.email | lowercase}}</td>
<td>{{user.address.city}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
I want to turn the email addresses in the table into email links: <a :href="mailto:user.email | lowercase">{{user.email | lowercase}}.
The line above results in an Error compiling template and prevents the rendering of the table (even though <a :href="user.email | lowercase">{{user.email | lowercase}}does alow rendering.
Where am I wrong? What is a viable solution?
You are mixing up the mailto inside a string with those email addresses.
Try this:
<td><a :href="'mailto:' + user.email | lowercase">{{user.email | lowercase}}</a></td>
var app = new Vue({
el: '#app',
data () {
return {
users: null,
loading: true,
errored: false
}
},
mounted () {
axios
.get('https://jsonplaceholder.typicode.com/users')
.then(response => {
this.users = response.data
})
.catch(error => {
console.log(error)
this.errored = true
})
.finally(() => this.loading = false)
}
});
Vue.filter('lowercase', function (value) {
return value.toLowerCase();
})
<script src="https://unpkg.com/axios#0.18.0/dist/axios.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="container">
<div class="panel panel-default table-container">
<div class="panel-heading">Users</div>
<div class="panel-body">
<table class="table table-striped table-bordered" id="dataTable">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Email</th>
<th>City</th>
</tr>
</thead>
<tbody>
<tr v-for="(user, index) in users">
<td>{{index + 1}}</td>
<td>{{user.name}}</td>
<td><a :href="'mailto:' + user.email | lowercase">{{user.email | lowercase}}</a></td>
<td>{{user.address.city}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
My guess is that the | lowercase pipe / filter requires one argument and you're attempting to add two strings together ('mailto:' + user.email) immediately before it.
Try replacing with either: :href="('mailto:' + user.email) | lowercase"
or making 'mailto:' + user.email a computed property

How to alert out the value of an option box in React?

I would like to get the values of the option boxes. Here's the sample code I wrote. I am trying to populate the option boxes from arrays. I can tell you details if needed for the solution. Thank you for your help in advance!
import React from 'react';
class Scooters extends React.Component {
static defaultProps = {
cat_brand: ['Honda', 'Peugeot', 'Yamaha'],
cat_cc: ['50cc', '125cc', '150cc', '250cc', '300cc'],
cat_price: ['20-70 €', '80-120 €', '130-160 €']
}
btnClick() {
alert('Button has been clicked...');
{/* I would like to alert here the selected options of the boxes. */}
}
render() {
let Brand_categoryOptions = this.props.cat_brand.map(categoryBrand => {
return <option key={categoryBrand} value={categoryBrand}>{categoryBrand}</option>
});
let Cc_categoryOptions = this.props.cat_cc.map(categoryCc => {
return <option key={categoryCc} value={categoryCc}>{categoryCc}</option>
});
let Price_categoryOptions = this.props.cat_price.map(categoryPrice => {
return <option key={categoryPrice} value={categoryPrice}>{categoryPrice}</option>
});
return (
<div>
<div className="container-fluid content">
<h2 className="text-center mt-2">Choose from our Scooters</h2>
<br></br>
<form>
<div class="container col-lg-4 mt-5">
<table class="table table-bordered">
<tr><th>Specifications</th> <th>Set the parameters</th></tr>
<tr><td>Scooter Brand</td> <td><select ref="cat_brand">{Brand_categoryOptions}</select></td></tr>
<tr><td>Engine CC</td> <td><select ref="cat_cc">{Cc_categoryOptions}</select></td></tr>
<tr><td>Unit Price</td> <td><select ref="cat_price">{Price_categoryOptions}</select></td></tr>
<tr><th>Action</th> <th><button onClick={this.btnClick}>Search</button></th></tr>
</table>
</div>
</form>
</div>
</div>
);
}
};
export default Scooters;
You need to add event handler function to select element and store the value in state. Also don’t forget to bind your btnClick function in constructor or use arrow function instead
Below code would work
dropDownChange = e => {
this.setState({
value: e.target.value
});
}
btnClick = () => {
alert('Option selected ', this.state.value);
}
<select ref="cat_price" onChange={this.dropDownChange} value={this.state.value}>{Price_categoryOptions}</select>
Try this. I added an onChange handler on the form which takes the change event, and sets the components state respectively (the state is initialized with a value from your default props, so that if you selected nothing and click it has the default values).
It gets the name attribute on the select element and the value from the event target. And on submit you prevent the default behavior which is the submit, so you can do whatever you want with your data.
class Scooters extends React.Component {
static defaultProps = {
cat_brand: ['Honda', 'Peugeot', 'Yamaha'],
cat_cc: ['50cc', '125cc', '150cc', '250cc', '300cc'],
cat_price: ['20-70 €', '80-120 €', '130-160 €']
}
state = {
cat_brand: this.props.cat_brand[0],
cat_cc: this.props.cat_cc[0],
cat_price: this.props.cat_price[0],
}
onChange = (event) => {
const { name, value } = event.target;
this.setState({ [name]: value })
}
btnClick = (event) => {
event.preventDefault();
console.log(this.state);
}
render() {
let Brand_categoryOptions = this.props.cat_brand.map(categoryBrand => (<option key={categoryBrand} value={categoryBrand}>{categoryBrand}</option>));
let Cc_categoryOptions = this.props.cat_cc.map(categoryCc => (<option key={categoryCc} value={categoryCc}>{categoryCc}</option>));
let Price_categoryOptions = this.props.cat_price.map(categoryPrice => (<option key={categoryPrice} value={categoryPrice}>{categoryPrice}</option>));
return (
<div>
<div className="container-fluid content">
<h2 className="text-center mt-2">Choose from our Scooters</h2>
<br></br>
<form onChange={this.onChange}>
<div className="container col-lg-4 mt-5">
<table className="table table-bordered">
<tbody>
<tr>
<th>Specifications</th>
<th>Set the parameters</th>
</tr>
<tr>
<td>Scooter Brand</td>
<td>
<select name="cat_brand" ref="cat_brand">{Brand_categoryOptions}</select>
</td>
</tr>
<tr>
<td>Engine CC</td>
<td>
<select name="cat_cc" ref="cat_cc">{Cc_categoryOptions}</select>
</td>
</tr>
<tr>
<td>Unit Price</td>
<td>
<select name="cat_price" ref="cat_price">{Price_categoryOptions}</select>
</td>
</tr>
<tr>
<th>Action</th>
<th>
<button onClick={this.btnClick}>Search</button>
</th>
</tr>
</tbody>
</table>
</div>
</form>
</div>
</div>
);
}
};

Categories