How integrate paypal into vue app using vue js? - javascript

I am having difficulty to integrate paypal into my web page using vue. I am getting any paypal button. If I use the same code in the vue cli then it's working but when I am using this code in index.html using vue cdn then it's not working. I need it to work in index.html without using the cli. Can anyone help me please?
HTML code
<div id="app">
<payment-method></payment-method>
</div>
Vue js Code
<script>
// Define a new component called button-counter
Vue.component('payment-method', {
template: '<div>'+
'<div v-if="!paidFor">'+
'<h1>Buy this Lamp - ${{ product.price }} OBO</h1>'+
'<p>{{ product.description }}</p>'+
'</div>'+
'<div v-if="paidFor">'+
'<h1>Noice, you bought a beautiful lamp!</h1>'+
'</div>'+
'<div ref="paypal"></div>'+
'</div>',
data: function() {
return {
loaded: false,
paidFor: false,
product: {
price: 777.77,
description: "leg lamp from that one movie",
img: "./assets/lamp.jpg"
}
};
},
mounted: function() {
const script = document.createElement("script");
script.src ="https://www.paypal.com/sdk/js?client-id=client-id=YOUR-CLIENT-ID";
script.addEventListener("load", this.setLoaded);
document.body.appendChild(script);
},
methods: {
setLoaded: function() {
this.loaded = true;
window.paypal
.Buttons({
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [
{
description: this.product.description,
amount: {
currency_code: "USD",
value: this.product.price
}
}
]
});
},
onApprove: async (data, actions) => {
const order = await actions.order.capture();
this.paidFor = true;
console.log(order);
},
onError: err => {
console.log(err);
}
}).render(this.$refs.paypal);
}
}
})
var vue = new Vue({
el: '#app',
data: {
}
})
</script>

Related

Importing PayPal (or any other script) from URL inside component in Vue

I have component named CallToAction and I would like to import PayPal, use their button and activate it with the script but I am not exactly sure how to properly import script from URL inside Vue component (I don't want to have it global on every page, only import it on pages that render CallToAction component).
I have tried following but I am unable to access variables from that script even though I can see it in html.
<template>
<div class="paypal-button" id="paypal-plan-container"></div>
</template>
<script>
export default {
mounted: function() {
let paypalScript = document.createElement('script')
paypalScript.setAttribute('src', 'https://www.paypal.com/sdk/js?client-id=sb&vault=true')
document.head.appendChild(paypalScript)
paypal.Buttons({
createSubscription: function(data, actions) {
return actions.subscription.create({
'plan_id': 'sb'
});
},
onApprove: function(data, actions) {
alert(data.subscriptionID);
}
}).render('#paypal-plan-container');
}
}
</script>
Gives this error ReferenceError: paypal is not defined
Here is the component I used
<template>
<div ref="paypal"></div>
</template>
<script>
export default {
data() {
return {
order: {
description: "Buy thing",
amount: {
currency_code: "USD",
value: 1000
}
}
};
},
mounted: function() {
const script = document.createElement("script");
const ClientID = "";
script.src = `https://www.paypal.com/sdk/js?client-id=${ClientID}`;
script.addEventListener("load", this.setLoaded);
document.body.appendChild(script);
},
methods: {
setLoaded: function() {
window.paypal
.Buttons({
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [this.order]
});
},
onApprove: async (data, actions) => {
const order = await actions.order.capture();
// ajax request
},
onError: err => {
console.log(err);
}
})
.render(this.$refs.paypal);
}
}
};
</script>
When a script expects to be included directly in the page, it's probably worth looking for a vue wrapper to take care of the issue of loading it via a vue component. Is this what you need?

Passing data to one of many components

I am trying to create a DownloadButton component in VueJS that animates when clicked, and stops animating upon completion of the download. The DownloadButton component will be used in a table where its repeated many times. I want the download method to be contained in the parent. The problem is that changing the loading variable causes all the components to be affected rather than just the one being clicked.
Parent:
<DownloadButton #click.native="download" :loading="loading"></DownloadButton>
<DownloadButton #click.native="download" :loading="loading"></DownloadButton>
<DownloadButton #click.native="download" :loading="loading"></DownloadButton>
methods: {
download() {
this.loading = true
// wait for the download procedure to finish...
this.loading = false
}
}
You should monitor loading state of each button not just global loading.
Here is quick and simple example of what you want I think:
Vue.component("download-button", {
template: "#dbTemplate",
props: ['loading'],
computed: {
stateText() {
return this.loading ? 'Loading...' : 'Load';
}
}
});
new Vue({
el: "#app",
data: {
resources: [
{ date: new Date(), url: "some-url1" },
{ date: new Date(), url: "some-url2" },
{ date: new Date(), url: "some-url3" },
{ date: new Date(), url: "some-url4" }
],
resourceStates: {}
},
methods: {
downloadResource(resource) {
this.$set(this.resourceStates, resource.url, true);
new Promise((resolve, reject) => {
setTimeout(() => resolve(new Date()), 1000);
}).then((date) => {
resource.date = date;
this.$set(this.resourceStates, resource.url, false);
})
},
isLoading(resource) {
return !!this.resourceStates[resource.url];
}
}
});
<script src="https://unpkg.com/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<div v-for="res in resources" :key="res.url" style="padding: 10px 0">
{{ res.date.toLocaleString() }}
<download-button #click.native="downloadResource(res)" :loading="isLoading(res)">
</download-button>
</div>
</div>
<script type="text/template-x" id="dbTemplate">
<button :disabled="loading">
{{ stateText }}
</button>
</script>

Vue.js uncaught reference error

Learning Vue and stuck. I have a brand new Laravel 5.4 project that I am using to learn Vue concepts, using Pusher/Echo. All is working in terms of message broadcasting, and the messages are fetched from the server and displayed on page load as expected. I want to programatically (from somewhere else in the project) send a message into the queue.
I am using this example as guide to accessing the Vue method outside the instance.
Why can I not access the instance method from my main JS file? The project is compiled with webpack FYI.
My Vue.js file:
$(document).ready(function()
{
Vue.component('chat-system', require('../components/chat-system.vue'));
var chatSystem = new Vue({
el: '#system-chat',
data: {
sysmessages: []
},
created() {
this.fetchMessages();
Echo.private(sys_channel)
.listen('SystemMessageSent', (e) => {
this.sysmessages.unshift({
sysmessage: e.message.message,
player: e.player
});
});
},
methods: {
fetchMessages() {
axios.get(sys_get_route)
.then(response => {
this.sysmessages = response.data;
});
},
addMessage(sysmessage) {
this.sysmessages.unshift(sysmessage);
this.$nextTick(() => {
this.$refs.sysmessages.scrollToTop();
});
axios.post(sys_send_route, sysmessage)
.then(response => {
console.log(response.data);
});
},
sendMessage(sysmessage) {
if (sysmessage !== '') {
this.$emit('systemmessagesent', {
player: this.player,
message: sysmessage
});
}
}
}
});
});
My Vue.js component:
<template>
<div id="round-status-message" class="round-status-message">
<div class="row">
<div class="col-xs-12" v-for="sysmessage in sysmessages">
{{ sysmessage.message }}
</div>
</div>
</div>
</template>
<script>
export default {
props: ['player', 'sysmessages'],
data() {
return {
newSysMessage: ''
}
},
methods: {
scrollToTop () {
this.$el.scrollTop = 0
},
sendMessage() {
this.$emit('systemmessagesent', {
player: this.player,
message: this.newSysMessage
});
this.newSysMessage = ''
}
}
};
</script>
I want to send a message into the queue programatically, so in my app.js, to test, I do:
// TESTING SYSTEM MESSAGES - DELETE
window.setInterval(function(){
var resp = {};
resp.data = {
id: 1,
message: "She hastily put down yet, before the end of half.",
progress_id: 1,
created_at: "2017-08-17 14:01:11",
updated_at: "2017-08-17 14:01:11"
};
chatSystem.$refs.sysmessages.sendMessage(resp);
console.log(resp);
}, 3000);
// TESTING SYSTEM MESSAGES - DELETE
But I get Uncaught ReferenceError: chatSystem is not defined
All I needed was to make the method name available to the global scope?
global.chatSystem = chatSystem; // App variable globally
This seems to work now...

Vue.js with laravel 5.3

I'm using Laravel 5.3 with Vue.js(very new to this).
Here's my current code
app.js
var vm = new Vue({
el: '#app',
data: {
messages: []
},
ready: function(){
this.getMessages();
},
methods: {
getMessages: function(){
this.$http.get('api/messages').then((response) => {
this.$set('messages', data);
}, (response) => {
});
}
}
});
api.php route is very simple
Route::get('/messages', function() {
return Message::latest()->get();
});
Note: here when i try access the route directly as localhost:8000/api/messages i get the array with the full data
On my view i have
<div class="content" id="app">
<tr v-for="message in messages">
<td> #{{ message}} </td>
</tr>
</div>
I have included online libraries for all jquery, vue.js, and vue.resource.
When i use vue.js debugger it shows that it returns messages[] but it's empty.
I have followed a lot of examples but couldn't get it to work.
Any help is greatly appreciated
if you are using vue.js 2.0 , ready is deprecated now, you may use mounted instead
mounted: function () {
this.$nextTick(function () {
this.getMessages();
})
}
Vue.js Docs
Since you are using the arrow syntax, then I switched to full ES2015 Code
getMessages() {
this.$http.get('api/messages')
.then( result => {
this.messages = result.json()
})
}
Try this:
var vm = new Vue({
el: '#app',
data: {
messages: []
},
ready: function(){
this.getMessages();
},
methods: {
getMessages: function(){
let ctrl = this;
this.$http.get('api/messages').then((response) => {
this.messages = response.data;
});
}
}
});

VueJS Resource reload content

Resource file helper/json.json
{
"content": {
"content_body": "<a href='#' v-on:click.prevent='getLink'>{{ button }}</a>",
"content_nav": "",
}
}
Vue main.js file
new Vue({
el: 'body',
data: {
text: 'Lorem sss',
},
methods: {
getLink: function(){
this.$http.get('http://localhost/vuejs/helper/json.json').then((resp) => {
this.$set('text', resp.data.content.content_body);
}, (resp) => {
console.log('error');
})
}
}
})
Output: Not Renderer
{{ button }}
Event does not work when the button is clicked. Data can not be loaded.
Vue.resourse have no relation to this problem
becouse html string from json isn't compiled.
Here a little test based on your example:
<body>
<div v-el:sample></div>
</body>
var test = new Vue({
el: 'body',
data: {
button: 'Lorem sss',
},
methods: {
getLink: function(){
var r = Math.floor(Math.random() * (4 - 1)) + 1;
this.$set('button', ['','btn1','btn2','btn3'][r] );
},
getCompiled: function() {
$(this.$els.sample).empty()
var element = $(this.$els.sample).append("<a href='#' v-on:click.prevent='getLink'>{{ button }}</a>");
this.$compile(element.get(0));
$(this.$els.sample).prepend('<p>Compiled button:</p>')
}
},
ready: function() {
this.getCompiled();
}
})
jsfidle

Categories