I'm starting to use vuetify along with a 'payment gateway' that I'm learning, but I've had a little problem.
If I have a form like this:
<form #submit.prevent="continuar" id="customer-form">
<div class="card-errors"></div>
<div class="form-group">
<label>Nombre del usuario de tarjeta</label>
<input type="text" data-epayco="card[name]">
</div>
<div class="form-group">
<label>Email</label>
<input type="text" data-epayco="card[email]">
</div>
...
<button type="submit">¡Pagar ahora!</button>
</form>
The "Token" parameter returns a value that is not undefined.
continuar(event){
ePayco.token.create(event.target, (error, token) => {
if(!error) {
console.log("token: " + token)
} else {
console.log(error)
}
})
},
But when I use vuetify the "Token" parameter returns "undefined" even when the "Epayco" library shows a message that everything has happened correctly.
<form id="customer-form" #submit.prevent="continuar">
<div class="card-errors"></div>
<v-layout row align-center>
<v-flex md3 offset-md1 class="mr-3">
<v-layout justify-end>
<span>Nombre en la tarjeta*</span>
</v-layout>
</v-flex>
<v-flex md4>
<v-text-field data-epayco="card[name]"/>
</v-flex>
</v-layout>
<v-layout row align-center>
<v-flex md3 offset-md1 class="mr-3">
<v-layout justify-end>
<span>Email</span>
</v-layout>
</v-flex>
<v-flex md4>
<v-text-field data-epayco="card[email]"/>
</v-flex>
</v-layout>
......
<v-layout class="my-3" justify-center>
<v-btn type="submit">Pagar</v-btn>
</v-layout>
</form>
Does anyone know why the problem?
It should be noted that when an error occurs the parameter 'error' returns the error and not undefined
According to the example here it appears you should be using the ePayco.token.create() function a bit differently.
epayco.token.create(paymentDetails)
.then(function(token) {
console.log(token);
})
.catch(function(err) {
console.log("err: " + err);
});
Related
I have this Component to create a recipe, but I want to store the data in the local storage.
When I print the "recipeData" it is printed on the console.
For example, I enter the name of the recipe and the description for it, etc. and I print the data in the console and the elements I have entered are printed, but when I print "recipeData.title" it is printed that it is not defined.
And when I want to store the recipeData in the local storage, it does not store it.
How can i solve the problem?
<template>
<v-app>
<v-container>
<v-layout row>
<v-flex xs12 sm6 offset-sm3>
<h2 class="btn-style">Create Recipe</h2>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs12>
<form #submit.prevent="onCreateRecipe">
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<v-text-field
name="title"
label="Title"
id="title"
v-model="title"
color="#43A047"
required
>
</v-text-field>
</v-flex>
</v-layout>
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<v-text-field
name="imageUrl"
label="ImageUrl"
id="imageUrl"
v-model="imageUrl"
color="#43A047"
required
>
</v-text-field>
</v-flex>
</v-layout>
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<img :src="imageUrl" height="300px" />
</v-flex>
</v-layout>
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<v-text-field
name="description"
label="Description"
id="description"
v-model="description"
color="#43A047"
multi-line
required
>
</v-text-field>
</v-flex>
</v-layout>
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<v-text-field
name="ingredients"
label="Ingredients"
id="ingredients"
v-model="ingredients"
color="#43A047"
multi-line
required
>
</v-text-field>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs12 sm6 offset-sm3>
<v-btn
class="green darken-1 color"
:disabled="!formIsValid"
type="submit"
>
Create Redcipe
</v-btn>
</v-flex>
</v-layout>
</form>
</v-flex>
</v-layout>
</v-container>
</v-app>
</template>
<script>
export default {
data() {
return {
title: "",
imageUrl: "",
description: "",
ingredients: "",
};
},
computed: {
formIsValid() {
return (
this.title !== "" &&
this.description !== "" &&
this.imageUrl !== "" &&
this.ingredients != ""
);
},
},
methods: {
onCreateRecipe() {
if (!this.formIsValid) {
return;
}
const recipeData = {
title: this.title,
description: this.description,
imageUrl: this.imageUrl,
ingredients: this.ingredients,
};
console.log(recipeData)
console.log("The Local Storage"+localStorage.setItem(this.recipeData));
}
}
};
</script>
<style scoped>
.btn-style {
color: #43a047;
}
.color {
color: #fafafa;
}
</style>
to store the data to localStorage, you have to define name of the storage first and then the data.
localStorage.setItem('storageName', recipeData)
to see the data of localStorage.
console.log(localStorage.getItem('StorageName'))
learn more https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
and theres no need this.recipeData because u declare the variable on the function. to get the data enought with recipeData
Local storage is a key-value data structure, you have to specify a key that will be used to retrieved the data from the storage as the first parameter. This is the syntax localStorage.setItem(keyName, keyValue);
Also, it has to be saved and retrieved as a string, stringifying it when saving and parsing it when getting it.
Your code for saving the object should be like this:
localStorage.setItem('recipeDataKey', JSON.stringify(this.recipeData));
and for retrieving:
const recipeData = JSON.parse(localStorage.setItem('recipeDataKey'));
I am working with an expansion panel that makes an API call when clicked, populating the v-card and v-layout with the response data. The challenge I am facing is that initially, the v-layout isn't populated.
If I comment out the v-flex elements, the v-layout will generate and display the expected number of rows (that are now empty and blank). Then, I uncomment the v-flex which displays the data properly within the v-layout.
Below is the template code I am using, alongside the API call that is being used when the v-expansion-panel-content is clicked:
<v-expansion-panel expand>
<v-expansion-panel-content v-for="(device, index) in devices" :key="index">
<div slot="header" #click="requestDeviceBreadcrumbs(device.id);">
<v-card flat>
<v-layout row wrap class="pa-3 project" :class="inAlarm(device)">
<v-flex xs12 md6>
<div class="caption grey--text">Location</div>
<div>{{ device.location }}</div>
</v-flex>
<v-flex xs6 sm4 md2>
<div class="caption grey--text">Address</div>
<div>{{ device.ip_address }}:{{ device.http_port_number }}</div>
</v-flex>
<v-flex xs6 sm4 md2>
<div class="caption grey--text">Manufacturer</div>
<div>{{ device.manufacturer }}</div>
</v-flex>
<v-flex xs2 sm4 md2>
<div class="right">
<v-chip small class="white--text caption my-2" :class="inAlarm(device)">
{{ device.alarm_count }}
</v-chip>
</div>
</v-flex>
</v-layout>
</v-card>
</div>
<v-card flat>
<v-layout row wrap class="pa-3 project" v-for="(breadcrumb, index) in device.breadcrumbs" :key="index" >
<v-flex xs12 md6>
<div class="caption grey--text">Oid</div>
<div>{{ breadcrumb.oid }}</div>
</v-flex>
<v-flex xs6 sm4 md3>
<div class="caption grey--text">Value</div>
<div>{{ breadcrumb.value }}</div>
</v-flex>
<v-flex xs6 sm4 md3>
<div class="caption grey--text">Timestamp</div>
<div>{{ breadcrumb.timestamp }}</div>
</v-flex>
</v-layout>
<v-divider></v-divider>
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>
And my API request function:
requestDeviceBreadcrumbs: function(device_id) {
axios({
method: "get",
url: `http://127.0.0.1:8000/api/v1/breadcrumbs/?device=${device_id}`
}).then(response => {
this.devices.find(obj => obj.id === device_id).breadcrumbs =
response.data;
});
}
My concern is that it's taking too long for the API to respond, is this the case? If so, what is acceptable way of handling this scenario?
Thank you.
Use Vue.set to add/update a reactive property to one device:
requestDeviceBreadcrumbs: function(device_id) {
axios({
method: "get",
url: `http://127.0.0.1:8000/api/v1/breadcrumbs/?device=${device_id}`
}).then(response => {
let device = this.devices.find(obj => obj.id === device_id)
this.$set(device, 'breacrumbs', response.data)
});
}
this my code :
<v-container grid-list-md fluid-fix>
<div v-for="(data ,c) in chapter.data" :key="c" class="my-3" style="border: 1px solid;">
<v-layout row wrap px-3>
<v-flex xs12 sm1>
<v-text-field v-model="data.num" label="Chapter"></v-text-field>
</v-flex>
<v-flex xs12 sm3>
<v-text-field v-model="data.name" label="name"></v-text-field>
</v-flex>
<v-flex xs12 sm8 d-flex>
<v-text-field v-model="data.description" label="short info" style="width: 100%;"></v-text-field>
<div>
<v-btn class="d-inline-flex servers--btn" color="success" #click="addServer(c)">add server</v-btn>
</div>
</v-flex>
</v-layout>
<v-container grid-list-md fluid-fix>
<v-layout wrap v-for="(server ,s) in data.servers" :key="s">
<v-flex sm12>
<div class="d-inline-flex">
<v-autocomplete
:items="data.serverlist"
v-model="server.server_id"
#input="serverChange(data)"
label="Server"
></v-autocomplete>
</div>
<div class="d-inline-flex text-xs-right pr-1">
<v-btn color="orange" class="white--text servers--btn" #click="demo_edit(c,s,server.links)">demo and Edit</v-btn>
</div>
<div class="d-inline-flex text-xs-right pr-1" style="float: right;">
<v-btn color="red" class="white--text servers--btn" #click="delSvOnChap(c,s)">Delete Server</v-btn>
</div>
</v-flex>
<v-flex sm12>
<v-textarea
v-model="server.links"
label="box image"
></v-textarea>
</v-flex>
</v-layout>
</v-container>
serverChange(data){
data.serverlist.forEach(obj => {
if(_.find(data.servers,{server_id: obj.value})){
obj.disabled = true
}else{
obj.disabled = false
}
});
},
serverChange is in methods
i want update disabled in the key has been determined , but it's update all object in array
when I log serverChange function i just see one object return and that's what I'm looking forward to but when i set disabled for this object , vue update all object in array
I need a solution for this problem .
I'm seeing lots of documentation for client-side validation with Vuetify, but finding it very difficult to find docs for server side validation messages for vuetify and vue.
PROBLEM
I have this component:
<template>
<v-container>
<v-layout row>
<v-flex xs12 sm6 offset-sm3>
<v-card>
<v-card-text>
<v-container>
<h3>Register Now</h3>
<form v-on:submit.prevent="onSubmit">
<v-layout row>
<v-flex xs12>
<v-text-field
name="email"
label="Email"
type="email"
ref="user_email"
id="email">
</v-text-field>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs12>
<v-text-field
name="password"
label="Password"
type="password"
ref="user_password"
id="password">
</v-text-field>
</v-flex>
</v-layout>
<v-layout row>
<v-flex xs12>
<v-btn type="submit">Sign Up</v-btn>
</v-flex>
</v-layout>
</form>
</v-container>
</v-card-text>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import axios from 'axios'
import router from 'vue-router'
export default {
data() {
return {
errors: [],
}
},
methods: {
onSubmit: function () {
axios.post('/users', {
user: {
email: this.$refs.user_email.value,
password: this.$refs.user_password.value
}
})
.then(response => {
})
.catch(error => {
this.errors.push(error.response.data.errors);
})
}
}
}
</script>
It basically collects errors that come back from the server. Those are the error messages I want to show if something goes wrong.
EXAMPLE:
If the email is blank, this will capture the "email_is_blank" message with the errors array. But how can I take that message and display it in the form using Vue.js and Vuetify?
Codepen example
One of the ways would be to create object with value and error string:
data: () => ({
email: {
value: '',
error: ''
}
})
Then bind your model to object value, and error-messages prop to object error:
<v-text-field
v-model="email.value"
label="email"
:error-messages="email.error"
></v-text-field>
In your response just change the value of error:
...
.then(response => {
this.email.error = response.errors.email // or whatever the path is to the relevant error message from the server
})
I am using avoriaz for testing in vuejs . Here is my code for testing and components.
<template>
<v-container fluid class="login-container">
<div class="hyperlogo">
<center>
<img src='../../../assets/logo.png' height="100" width="100">
<p>HyperEmail</p>
<a>v0.11.1</a>
</center>
</div>
<v-layout row wrap>
<v-flex xs6 md4 offset-md4>
<v-card class="login-card">
<v-card-text class="login-text">
<v-text-field
v-on:focus="focusUser"
label="Username"
placeholder="Username"
class="mt-5"
v-model="username"
#keyup.enter.native="validateData"
v-bind:rules="[userNameError]"
></v-text-field>
<v-text-field
v-on:focus="focusPassword"
label="Password"
placeholder="Password"
v-model="password"
type="password"
v-on:keyup.enter.native="validateData"
v-bind:rules="[passwordError]"
></v-text-field>
</v-card-text>
<div #click="validateData" class="button-style">
<v-btn block primary light >Login</v-btn>
</div>
</v-card>
</v-flex>
<Error v-if="error" :text="error.msg" :onDestroy="resetError" />
</v-layout>
</v-container>
</template>
For testing
import Login from '#/containers/views/login/Login.vue'
describe('Login.vue', () => {
it('checks text inside login component', () => {
const wrapper = mount(Login)
// let parent = wrapper.find('.hyperlogo')[0]
// expect(wrapper.contains('.hyperlogo')).to.equal(true)
if (wrapper.find('.hyperlogo')[0]) {
console.log('Yes it is there')
}
expect(wrapper.text()).to.equal('')
expect(wrapper.find('center')[0].is('center')).to.equal(true)
})
})
Here wrapper.find is not working
Error : - TypeError: Cannot read property 'is' of undefined .. Can anyone helps me to solve this type of error ??