Stripe-Vue payment POST 500 uncaught in promise - laravel

I think I messed something up with the csrf_field() but I did push the X-CSRF-TOKEN... I had a 419 error before but brought myself more into trouble...
The error
- POST /betaling 500
- Uncaught (in promise) Response {url: "/betaling", ok: false, status: 500, statusText: "Internal Server Error", headers: Headers
Header
<script>
var Cityofcompanies = {
csrfToken: "{{ csrf_token() }}",
stripeKey: "{{ config('services.stripe.key') }}"
};
Routes
Route::post('betaling', 'PaymentController#store')->name('payment');
App.js
window.Vue = require('vue');
require('vue-resource');
Vue.http.interceptors.push((request, next) => {
request.headers.set('X-CSRF-TOKEN', Cityofcompanies.csrfToken);
next();
});
Vue.component('CheckoutForm',
require('./components/CheckoutForm.vue'));
CheckoutForm.vue
<template>
<form action="/betaling" method="POST">
<input type="hidden" name="stripeToken" v-model="stripeToken">
<input type="hidden" name="stripeEmail" v-model="stripeEmail">
<button type="submit" #click.prevent="buy">Abonneer</button>
</form>
</template>
<script>
export default {
data() {
return {
stripeEmail: '',
stripeToken: ''
};
},
created() {
this.stripe = StripeCheckout.configure({
key: Cityofcompanies.stripeKey,
image:"https://stripe.com/img/documentation/checkout/marketplace.png",
locale: "auto",
currency: "eur",
token: (token) => {
this.stripeToken = token.id;
this.stripeEmail = token.email;
this.$http.post('/betaling', this.$data);
//.then(response => alert('Bedankt voor het abonneren!'));
}
});
},
methods: {
buy() {
this.stripe.open({
name: "Abonneer voor 1 jaar",
description: "Professional Version",
amount: 5000,
});
}
}
}
</script>
Show.blade.php
<div id="checkout">
<checkout-form></checkout-form>
</div>
<script>
window.onload = function () {
const app = new Vue({
el: '#checkout'
});
}
</script>
<script src="https://checkout.stripe.com/checkout.js"></script>

You'll need to look at the logs for the /betaling endpoint to see what the error might be here.

Related

How to check if a laravel validator response is an error or not with Vue.js

I am using Laravel 7 and Vue.js 2.
I make a delete call with axios and if everything is correct I receive as a response the new data in the related tables to update a select and if there is an error I receive the errors of the Laravel validator.
The problem is that I have to understand with javascript if the response is an error or not... but I don't know how to do that.
This is my Vue component:
<template>
<form method="DELETE" #submit.prevent="removeTask">
<div class="form-group">
<title-form v-model="titleForm" :titleMessage="titleForm"></title-form>
</div>
<hr>
<div class="form-group">
<label for="tasks">Tasks:</label>
<select required v-model="user.tasks" class="form-control" id="tasks" #mouseover="displayResults(false, false)">
<option v-for="task in tasks_user" :value="task.id" :key="task.id">
{{ task.task_name }} - {{ task.task_description }}
</option>
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
<hr>
<div class="form-group">
<validated-errors :errorsForm="errors" v-if="displayErrors===true"></validated-errors>
<!--<success-alert :success_message="successMessage" v-if="displaySuccess===true"></success-alert>-->
</div>
</form>
</template>
<script>
import ValidatedErrors from "./ValidatedErrors.vue"
import SuccessAlert from "./SuccessAlert.vue"
import TitleForm from "./TitleForm.vue"
export default {
components: {
'validated-errors': ValidatedErrors,
'success-alert': SuccessAlert,
'title-form': TitleForm
},
mounted() {
console.log('Component mounted.');
},
props: {
tasks_user: {
type: Array,
required: true,
default: () => [],
}
},
computed: {
titleForm: function () {
return "Remove a task from " + this.tasks_user[0].user_name;
}
},
data: function() {
return {
user: {
tasks: ""
},
errors: {},
displayErrors: false,
displaySuccess: false,
successMessage: "The task has been removed."
}
},
methods: {
removeTask: function() {
alert(this.user.tasks);
//axios.delete('/ticketsapp/public/api/remove_task_user?id=' + this.user.tasks)
axios.delete('/ticketsapp/public/api/remove_task_user?id=' + 101)
.then((response) => {
console.log(response.data);
if(typeof response.data[0].task_id !== "undefined") {
alert("There are no errors.");
} else {
alert("There are errors.");
}
if (typeof response.data[0].task_id === "undefined") { //problem
alert('noviva');
console.log(response.data);
this.errors = response.data;
this.displayErrors = true;
} else {
alert('viva');
this.tasks_user = response.data;
this.errors = {};
}
})
.catch(error => {
alert(noooooo);
console.log(error);
});
},
displayResults(successShow, errorShow) {
this.displayErrors = errorShow;
this.displaySuccess = successShow;
}
},
}
</script>
This is my method in the controller:
public function remove(Request $request) {
$validator = Validator::make($request->all(), [
'id' => 'required|exists:task_user,id'
]);
if ($validator->fails()) {
return response($validator->errors()); //problem
}
$task_user_id = $request->id;
$user_id = TaskUser::where('id', $task_user_id)->pluck('user_id')->first();
TaskUser::find($task_user_id)->delete();
$tasks_user = TaskUser::with(['user', 'task'])->get();
$tasks_user = TaskUser::where('user_id', $user_id)->get();
$tasks_user = TaskUserResource::collection($tasks_user);
return json_encode($tasks_user);
}
To distinguish the type of return I created this condition: if (typeof response.data[0].task_id === "undefined") but when that condition is true everything falls down and I receive the following error in the console:
Uncaught (in promise) ReferenceError: noooooo is not defined
So how can I do to distinguish the type of return of the API call?

Real-time search engine with VueJS and Laravel

I am doing the search engine section in VueJS and Laravel, but I have a problem that does not allow me to advance in the other sections. The search engine opens and everything but when I write it only sends the first letter or 2 but not all of them like this in this image:
image of the data you send
the data that I write
After that it shows me the following error in console:
Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/search?q=th"
Now showing my search engine code:
<template>
<div class="form_MCycW">
<form autocomplete="off" #sumbit.prevent>
<label class="visuallyhidden" for="search">Search</label>
<div class="field_2KO5E">
<input id="search" ref="input" v-model.trim="query" name="search" type="text" placeholder="Search for a movie, tv show or person..." #keyup="goToRoute" #blur="unFocus">
<button v-if="showButton" type="button" aria-label="Close" #click="goBack">
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15"><g fill="none" stroke="#fff" stroke-linecap="round" stroke-miterlimit="10" stroke-width="1.5"><path d="M.75.75l13.5 13.5M14.25.75L.75 14.25"/></g></svg>
</button>
</div>
</form>
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
data() {
return {
query: this.$route.query.q ? this.$route.query.q : ''
}
},
computed: {
showButton() {
return this.$route.name === 'search';
},
...mapState({
search: state => state.event.fromPage
})
},
mounted() {
this.$refs.input.focus();
},
methods: {
goToRoute() {
if (this.query) {
this.$router.push({
name: 'search',
query: { q: this.query },
});
} else {
this.$router.push({
path: this.fromPage,
});
}
},
goBack() {
this.query = '';
this.$router.push({
path: '/',
});
},
unFocus (e) {
if (this.$route.name !== 'search') {
const target = e.relatedTarget;
if (!target || !target.classList.contains('search-toggle')) {
this.query = '';
this.$store.commit('closeSearch');
}
}
}
}
}
</script>
This is the other section of the search engine:
<template>
<main class="main">
<div class="listing">
<div class="listing__head"><h2 class="listing__title">{{ title }}</h2></div>
<div class="listing__items">
<div class="card" v-for="(item, index) in data.data" :key="index">
<router-link :to="{ name: 'show-serie', params: { id: item.id }}" class="card__link">
<div class="card__img lazyloaded"><img class="lazyload image_183rJ" :src="'/_assets/img/covers/posters/' + item.poster" :alt="item.name"></div>
<h2 class="card__name">{{ item.name }}</h2>
<div class="card__rating">
<div class="card__stars"><div :style="{width: item.rate * 10 + '%'}"></div></div>
<div class="card__vote">{{ item.rate }}</div>
</div>
</router-link>
</div>
</div>
</div>
</main>
</template>
<script>
import { mapState } from 'vuex';
let fromPage = '/';
export default {
name: "search",
metaInfo: {
bodyAttrs: {
class: 'page page-search'
}
},
computed: {
...mapState({
data: state => state.search.data,
loading: state => state.search.loading
}),
query() {
return this.$route.query.q ? this.$route.query.q : '';
},
title() {
return this.query ? `Results For: ${this.query}` : '';
},
},
async asyncData ({ query, error, redirect }) {
try {
if (query.q) {
this.$store.dispatch("GET_SEARCH_LIST", query.q);
} else {
redirect('/');
}
} catch {
error({ message: 'Page not found' });
}
},
mounted () {
this.$store.commit('openSearch');
this.$store.commit('setFromPage', fromPage);
if (this.data.length == 0 || this.data === null) {
this.$store.dispatch("GET_SEARCH_LIST", this.query);
}
setTimeout(() => {
this.showSlideUpAnimation = true;
}, 100);
},
beforeRouteEnter (to, from, next) {
fromPage = from.path;
next();
},
beforeRouteUpdate (to, from, next) {
next();
},
beforeRouteLeave (to, from, next) {
const search = document.getElementById('search');
next();
if (search && search.value.length) {
this.$store.commit('closeSearch');
}
}
};
</script>
In my routes section it is defined as follows:
{
name: 'search',
path: '/search',
component: require('../views/' + themeName + '/control/search/index').default
}
It is supposed to be a real-time search engine. I would appreciate your help in solving this problem...
What you need is a debounce. What it does is that it wait or delay till the user had finished typing before the model get updated or before you send it to the server.
An example of how it works is here
Here is a package for it.
https://github.com/vuejs-tips/v-debounce

Trying to get a single data and display in a vue component, but nothing is displaying

I am using Laravel 5.8 + Vue.js in my project.
Trying to get a single data from a controller but nothing is displaying.
I added the 12345 in the component to check if the component is working, 12345 is showing well.
controller
public function getSingleData($idx)
{
$paymentData = PaymentData::where('idx', $idx)->first();
return view('paydetail')->with('paymentData', $paymentData);
}
router
Route::view('/paylist', 'paylist')->name('paylist.view');
Route::get('/paylist/data', 'PaymentController#getPaymentData')->name('paylist');
Route::get('/paydetail/{idx}', 'PaymentController#getSingleData')->name('paydetail');
blade
#extends('layouts.default')
#section('content')
<div class="container">
<paydetail :idx="{{ $paymentData->idx }}"></paydetail>
app.js
Vue.component('paydetail', require('./components/Paydetail.vue').default);
Paydetail.vue
<template>
<div>
<h2>12345</h2>
<div v-for="val in paymentData">
<h2>{{ val.app_name }} </h2>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
props: [ 'idx' ],
data() {
return {
paymentData: [{}],
}
},
created() {
this.paymentData = this.getPayDetailData();
console.log(this.idx);
console.log("here");
},
methods: {
getPayDetailData() {
axios({
method: 'GET',
url: '/paydetail/'+ this.idx
}).then(
response => {
console.log(response)
return response
},
error => {
console.log(error)
}
)
},
},
}
</script>
The result of console.log(response) is weird. It shows the whole html document which I don't understand at all.
It shows like this.
{data: "<!DOCTYPE html>↵<html>↵ <head>↵ <meta ch…>↵<!-- For Datatable -->↵↵↵ </body>↵</html>↵", status: 200, statusText: "OK", headers: {…}, config: {…}, …}
What did I wrong here?

Vue.js component conflict in laravel blade view

I have 2 of the same components in my laravel blade view, but they are conflicting.
What i'm trying to accomplish:
I've made a vue component that uploads a file to firebase and stores it in my database. In my blade view i have 2 places where i want to use this component. I configure the component with props so the component knows where to store the file.
What going wrong:
Every time i try to upload a file with the second component, i fire the function in the first component. How do i fix that the components can't conflict?
My laravel balde view:
component 1
<uploadfile
:key="comp100"
:user_data="{{ Auth::user()->toJson() }}"
store_path="/users/{{ Auth::user()->username }}/settings/email_backgrounds"
:store_route="'settings.project_email'"
:size="1000"
fillmode="cover"
></uploadfile>
component 2
<uploadfile
:key="comp200"
:user_data="{{ Auth::user()->toJson() }}"
store_path="/users/{{ Auth::user()->username }}/settings/email_backgrounds"
:store_route="'settings.project_email'"
:size="1000"
fillmode="cover"
></uploadfile>
The Vue component:
<template>
<div class="vue-wrapper">
<FlashMessage position="right top"></FlashMessage>
<div v-if="loading" class="lds-dual-ring"></div>
<div class="field">
<div class="control">
<label class="button main-button action-button m-t-20" for="uploadFiles"><span style="background-image: url('/images/icons/upload.svg')"></span>Kies bestand</label>
<input type="file" name="uploadFiles" id="uploadFiles" class="dropinput" #change="selectFile">
</div>
</div>
</div>
</template>
<script>
import { fb } from '../../firebase.js';
export default {
data() {
return {
fileObject: {
filePath: null,
url: null,
file: null,
resizedPath: null
},
loading: false
};
},
mounted() {
console.log(this.size)
console.log(this.fillmode)
},
props: [
'user_data',
'store_path',
'store_route',
'size',
'fillmode'
],
methods: {
selectFile(event)
{
var file = event.target.files[0];
this.fileObject.file = file
this.fileObject.filePath = this.store_path + '/' + file.name
this.fileObject.resizedPath = this.store_path + '/resized-' + file.name
if(file.type == 'image/png' || file.type == 'image/jpeg')
{
this.uploadFile(this.fileObject)
} else {
this.flashMessage.success({
title: 'Oeps!',
message: 'De afbeelding moet een png of een jpeg zijn!',
blockClass: 'success-message'
});
}
},
uploadFile(fileObject)
{
var vm = this
console.log(fileObject)
var storageRef = fb.storage().ref(fileObject.filePath)
var uploadTask = storageRef.put(fileObject.file)
this.loading = true
uploadTask.on('state_changed', function(snapshot){
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
},function(error) {
}, function() {
var resizeImage = fb.functions().httpsCallable('resizeImage')
resizeImage({filePath: fileObject.filePath, contentType: fileObject.file.type, watermark: false, size: vm.size, fit: vm.fillmode}).then(function(result){
var downloadRef = fb.storage().ref(fileObject.resizedPath);
downloadRef.getDownloadURL().then(function(url){
fileObject.url = url
vm.loading = false
vm.storeImage(fileObject)
}).catch(function(error){
console.log(error)
})
}).catch(function(error){
});
});
},
storeImage(file)
{
axios.post('/api/app/store_file', {
api_token: this.user_data.api_token,
user: this.user_data,
file: file,
storeRoute: this.store_route
}).then((res) => {
location.reload()
}).catch((e) => {
});
}
}
}
</script>
Does someone know how to fix this?

How to Pass CSRF token with AJAX request Laravel + Vue.js

I have a Vue.js component...
<template>
<form method="POST" action="/login">
<button class="btn btn-primary center-block" #click="$emit('buttonClicked')">
Login
</button>
</form>
</template>
<script>
var axios = require('axios');
Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('content');
export default {
created: function () {
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
},
props: ['show'],
name: "login-component",
methods: {
close: function () {
this.$emit('close');
},
buttonClicked: function () {
axios.post('/login', {data: this.data})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error.message);
});
}
}
}
</script>
My csrf exists in meta:
<meta id="token" name="csrf-token" content="{{ csrf_token() }}">
But it doesn't pass with the Ajax request instead I get...
419 unknown status and no _token in console->Form Data
What am I doing wrong?
I tried to use...
window.axios.defaults.headers.common = {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN' : document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
};
But it didn't help.
I solved by this way:
export default {
data() {
return {
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
},
...
And inside <form></form>:
<input type="hidden" name="_token" :value="csrf">

Resources