Using generated Stripe checkout button - javascript

I'm trying to implement in my VueJS Project a checkout button generated from the Stripe Dashboard.
I feel like i'm not doing it the right way, so if you have advises i would like to hear them.
I have add <script src="https://js.stripe.com/v3/"></script> in index.html.
the 1st error i get
the 2nd error i get
Here is my Vue component.
<template>
<div>
<button
style="background-color:#6772E5;color:#FFF;padding:8px 12px;border:0;border-radius:4px;font-size:1em"
id="checkout-button-MY_PLAN"
role="link"
>
Checkout
</button>
<div id="error-message"></div>
</div>
</template>
<script>
(function() {
let stripe = Stripe('MY_KEY');
let checkoutButton = document.getElementById('MY_PLAN');
checkoutButton.addEventListener('click', function () {
stripe.redirectToCheckout({
items: [{plan: 'MY_PLAN', quantity: 1}],
successUrl: '',
cancelUrl: '',
})
.then(function (result) {
if (result.error) {
let displayError = document.getElementById('error-message');
displayError.textContent = result.error.message;
}
});
});
})();
</script>
<style scoped>
</style>
If i can't use Stripe in a VueJS Project how can i get around the problem without modifying all my project ?

For the first error where Stripe is undefined. That is likely because the Stripe.js library isn't loaded before that code runs. You'll need to ensure that you've included Stripe.js [1] with this tag in your HTML before any of your JavaScript using Stripe is executed. Note that it's not loaded async.
<script src="https://js.stripe.com/v3/"></script>
The second error is because when you're attempting to getElementById the ID that you're passing is not the same as the ID in the HTML for the button.
The button's ID is checkout-button-MY_PLAN and the ID you're trying to find the button with by passing is MY_PLAN. I would recommend updating your call to getElementById to:
let checkoutButton = document.getElementById('checkout-button-MY_PLAN');
[1] https://stripe.com/docs/js/including

Related

How can I add a JavaScript event to my Django HTML template?

My current logout is GET, I just redirect the user to /auth/logout
However, I’ve discovered that this is unsafe and I trying to add a post to this redirection. By the way, my login is using django-allauth, so I am looking to use this concept here too. But, I need to do it with JavaScript because my front end is written in Vue.js.
https://django-allauth.readthedocs.io/en/latest/views.html#logout-account-logout
This is my javascript file where I use too much vue:
let userNavigation = [
{ name: 'Account', href: '/account/'},
{ name: 'Logout', href: '/auth/logout'}
]
This is my HTML using vue
const menu =
`
<MenuItems>
<MenuItem v-for="item in userNavigation" :key="item.name">
<a :href="item.href">
[[ item.name ]]
</a>
</MenuItem>
</MenuItems>
`
This is what I am trying to do to:
<script type="text/javascript">
function logoutPost() {
let form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', '/auth/logout/');
let csrf = document.createElement('input');
csrf.setAttribute('type', 'hidden');
csrf.setAttribute('name', 'csrfmiddlewaretoken');
csrf.setAttribute('value', '{{ csrf_token }}');
form.appendChild(csrf);
document.body.appendChild(form);
let logoutAnchor = document.getElementsByName('Logout')[0].value;
form.appendChild(logoutAnchor);
logoutAnchor.addEventListener('click', function (e) {
e.preventDefault();
form.submit();
console.log("logout clicked");
});
}
</script>
But, even if I try to add JavaScript DOM, nothing changes, I do not see anything in my console log and it just redirects. Where I am making a mistake?

Problems Adding Shopify Line Items to Cart with JS Buy SDK

Having some problems with the Shopify js-buy-SDK.
I have been able to make a cart, and I have also tried fetching products, etc, and it works. But when I try to add a line item to the cart, the updated cart array, from addLineItems, returns empty. I know the variantId is correct, because if I change it I get an error.
Full code:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://sdks.shopifycdn.com/js-buy-sdk/v1/latest/index.umd.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
const client = ShopifyBuy.buildClient({
domain: 'xxxx.myshopify.com',
storefrontAccessToken: 'xxxxxxx',
appId: '6'
});
// Create an empty checkout
client.checkout.create().then((checkout) => {
// Do something with the checkout
console.log(checkout.id);
x(checkout.id, client);
});
});
function x(check, client) {
const itemToAdd = [
{ variantId : 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzYyMDExMDQxMzg4NA==', quantity : 12 }
];
// Add an item to the checkout
client.checkout.addLineItems(check, itemToAdd).then((checkout) => {
console.log(checkout.lineItems); // THIS RETURNS AN EMPTY ARRAY
});
}
</script>
</head>
<body>
</body>
</html>
Are you using the productID or the variantID of the item you're trying to add?
In my experience, if an ID ends with == it's a productID.
Assuming the item you're trying to add only has one variant, try
const productId = 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzYyMDExMDQxMzg4NA==';
client.product.fetch(productId)
.then((product) => {
const variantId = product.variants[0].id;
console.log(variantId);
});
If you're seeing an ID-like string and not undefined in your console then that is the correct value for your variantID.

Uncaught TypeError: Cannot read property 'marksSession' of undefined

right now I am passing hard coded value for my name.
I am trying to pass the dynamic username for my name key inside my scriprt tag from sportsService.
its working fine in my ts file.
but its not working fine in my html file.
I am getting an error. ---> Uncaught TypeError: Cannot read property 'marksSession' of undefined
can you guys tell me how to pass inside script tag of .html.
providing my code below
index.html
<script>
(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/APP_ID';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()
</script>
<script>
let players=this.sportsService.marksSession();
console.log("players--->" + players);
if(players) {
this.userId = players.user_players.SSO[0];
}
Intercom('trackEvent', 'share-link');
window.intercomSettings = {
app_id: 'APP_ID',
name: "Jane Doe", // Full name
email: "customer#example.com", // Email address
created_at: 1312182000 // Signup date as a Unix timestamp
};
</script>
sports.ts
import { sportsService } from '../../services/sports.service';
constructor(public sportsService : sportsService){
}
ngOnInit() {
let that =this;
let players=this.sportsService.marksSession();
if(players) {
this.userId = players.user_players.SSO[0];
}
}
If you import your TypeScript file on your HTML page, that should take care of the TypeError you're getting. I believe you will need to compile your TypeScript to JavaScript prior to doing this.
Check out W3Schools for some info on how to use the tag in your HTML:
https://www.w3schools.com/tags/att_script_src.asp

Weird issue where after inserting a doc, it exists for an instant, and then deletes itself?

They way I'm testing this is a simple for loop in the template to run through the elements available to the client and display them in a list.
I insert the elements through a text input identified by #query.
When I enter an element, it displays for a brief instant, and a console log that prints out Links.find().fetch() shows that the element exists, and then shortly afterwards, the element is seemingly automagically removed making any successive calls to Links.find().fetch() yield an empty list. Is this a bug within Meteor? Or is it expected behaviour and bad implementation?
UPDATE
Another weird development, I added setTimeout(function(){Links.find().fetch()},3000); to the server side to try and track what was going on. With this line, the inserts work correctly for a while, and then crashes with these errors: http://i.imgur.com/CUYDO67.png
. What is going on?
Below is my template file myapp.html
<head>
<title>myapp</title>
</head>
<body>
{{> search_bar}}
<br>
{{> list_of_links}}
</body>
<template name="search_bar">
<h1>Playlist</h1>
<input id="query" type="text" placeholder="Enter Query Here"/>
</template>
<template name="list_of_links">
<ul id="item-list">
{{#each my_playlist}}
{{> link_item}}
{{/each}}
</ul>
</template>
<template name="link_item">
<li class="link">
<div class="link-title">{{youtube_link}} {{sess}}</div>
</li>
</template>
And here follows myapp.js
//Setting up a collection of urls
Links = new Meteor.Collection("links");
if (Meteor.isClient) {
//"Subscribing" to server's published data
Deps.autorun( function(){
Meteor.subscribe( "links", Meteor.default_connection._lastSessionId);
});
//Nuke database helper function -- debugging
Template.list_of_links.clean = function(collection) {
if(collection) {
// clean items
_.each(collection.find().fetch(), function(item){
collection.remove({_id: item._id});
});
}
}
//Songs from session
Template.list_of_links.my_playlist = function () {
return Links.find();
};
Template.search_bar.events({
//http://stackoverflow.com/a/13945912/765409
'keypress #query' : function (evt,template) {
// template data, if any, is available in 'this'
if (evt.which === 13){
var url = template.find('#query').value;
//Find a nicer way of clearing shit.
$("#query").val('');
Links.insert({sess:Meteor.default_connection._lastSessionId,youtube_link:url});
var cursor = Links.find();
cursor.rewind();
console.log(cursor.fetch());
//Add to database.
}
}
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
Meteor.publish("links", function( sess ) {
return Links.find({sess: sess}); //each client will only have links with that _lastSessionId
});
//Making sure permissions are correct
Links.allow({
insert: function (userId, doc) {
return true;
}
});
});
}
That kind of behavior is expected when user doesn't have enough privileges to create a document. The insert function creates a local copy of the doc instantly (thanks to latency compensation), and then sync it with the result of server operation. If that operation fails, the temporary document is purged from client's Minimongo.
Have you created proper rules with Collection.allow? That's the first place to look for the cause.

What's a good way to handle flash notifications in meteor (with meteor-router)?

I am using meteor along with meteor-router for client and server side routing. I'm wondering what a good way to handle site notifications, specifically "flash" type ones.
In the global layout.html I can have a handlebars output a message if a "message" session variable is set, but the message shouldn't stick around once the app is routed to a new url with Meteor.Router.to().
What's a good solution to having "flash" notifications? Or, how can I automatically clear a session variable after routing to a new URL.
layout.html:
<head>
<title>Meteor App</title>
</head>
<body>
{{> global-layout}}
</body>
<template name="global-layout">
{{#if message}}
<div class="message">{{message}}</div>
{{/if}}
{{renderPage}}
</template>
then in layout.js
Template['global-layout'].message = function () {
return Session.get('message');
};
I'm using a Meteor.Router.filter for this. This filter will be applied to all routes, therefore all flashes will be cleared on all url changes.
routes.js
Meteor.Router.filters({
// clearSeenMessages filter clears all seen messages.
// This filters is applied to all pages
clearSeenMessages: function (page) {
flash.clear();
return page;
},
});
// applies to all pages
Meteor.Router.filter('clearSeenMessages');
Here's the rest of the implementaion, aspects were borrowed from telesc.pe
client/views/flashes/flash_item.html
<template name="flashItem">
{{#if show}}
<div class="alert-box {{type}}">
{{message}}
<a class="close" href="">×</a>
</div>
{{/if}}
</template>
client/views/flashes/flash_item.js
// When the template is first created
Template.flashItem.created = function () {
// Get the ID of the messsage
var id = this.data._id;
Meteor.setTimeout(function () {
// mark the flash as "seen" after 100 milliseconds
flash.Flashes.update(id, {$set: {seen: true}});
}, 100);
}
client/views/flashes/flashes.html
<template name="flashes">
{{#each flashes}}
{{> flashItem}}
{{/each}}
</template>
client/views/flashes/flashes.js
Template.flashes.flashes = function () {
return flash.Flashes.find();
}
client/views/app.html
<body>
<!-- add the flashes somewhere in the body -->
{{> flashes}}
</body>
client/lib/flashes.js
// flashes provides an api for temporary flash messages stored in a
// client only collecion
var flash = flash || {};
(function (argument) {
// Client only collection
flash.Flashes = new Meteor.Collection(null);
// create given a message and optional type creates a Flash message.
flash.create = function (message, type) {
type = (typeof type === 'undefined') ? 'error' : type;
// Store errors in the 'Errors' local collection
flash.Flashes.insert({message: message, type: type, seen: false, show: true});
};
// error is a helper function for creating error messages
flash.error = function (message) {
return flash.create(message, 'error');
};
// success is a helper function for creating success messages
flash.success = function (message) {
return flash.create(message, 'success');
};
// info is a helper function for creating info messages
flash.info = function (message) {
return flash.create(message, 'info');
};
// clear hides viewed message
flash.clear = function () {
flash.Flashes.update({seen: true}, {$set: {show: false}}, {multi: true});
};
})();
Usage
flash.success('This is a success message');
flash.error('This is a error message');
flash.info('This is a info message');
You can now use the router-with-flash package available on atmosphere to handle flash notifications. If you use meteorite (which you should), you can do mrt add router-with-flash in the root directory of your project. Then, to display an alert you need to -
Meteor.Router.to("/", { alert: "Some alert..." });
Meteor.Router.notification("alert");
This will display the alert until the next call to Meteor.Router.to().

Categories