Turning the Stripe Checkout into a Synch function - meteor

I am trying to use wrapAsync for Stripe.charges call using Stripe Checkout, but I cant seem to get it working
Client code
Template.bookingPost2.events({
"click #accept": function(event, template){
event.preventDefault();
StripeCheckout.open({
key: 'public_key',
amount: 5000, // this is equivalent to $50
name: 'Meteor Tutorial',
description: 'On how to use Stripe ($50.00)',
panelLabel: 'Pay Now',
token: function(res) {
stripeToken = res.id;
console.info(res);
Meteor.call('chargeCard', stripeToken);
}
});
}
});
Server code
Meteor.methods({
'chargeCard': function(stripeToken) {
check(stripeToken, String);
var Stripe = StripeAPI('secret_key');
Stripe.charges.create({
source: stripeToken,
amount: 5000, // this is equivalent to $50
currency: 'usd'
}, function(err, charge) {
console.log(err, charge);
});
}
});
My tried Solution:
var stripeChargesCreateSync = Meteor.wrapAsync(Stripe.charges.create);
var result = stripeChargesCreateSync({
source: stripeToken,
amount: (info.timeRequired/15)*500, // this is equivalent to $50
currency: 'gbp'
});
And how do I handle the returned values namely charge and err?

This should work and result should populate with a result as you see in the stripe documentation:
var result = stripeChargesCreateSync({
source: stripeToken,
amount: (info.timeRequired/15)*500, // this is equivalent to $50
currency: 'gbp'
});
This is where the error is, use this:
var stripeChargesCreateSync = Meteor.wrapAsync(Stripe.charges.create, Stripe.charges);
instead of
var stripeChargesCreateSync = Meteor.wrapAsync(Stripe.charges.create);
Your stripeChargesCreateSync method needs to bind to the correct context when it runs. Meteor.wrapAsync doesn't know what that is so you need to tell it where the Stripe.charges.create method is.

Related

Show loader in Meteor reactive-table until data is ready for client

I have used meteor reactive-table https://github.com/aslagle/reactive-table for show data listing. How to use ready: ReactiveVar(Boolean) option in settings code?
Let's say your reactive table is showing data from a subscription. You would then have the ready() state of that subscription inform the reactive-table.
Template.myTemplate.onCreated(function(){
this.mySub = Meteor.subscribe('mySubscription');
});
Template.myTemplate.helpers({
settings: function () {
return {
collection: collection,
rowsPerPage: 10,
showFilter: true,
fields: ['name', 'location', 'year'],
ready: this.mySub.ready(),
};
}
});
Note that this requires you use ReactiveTable.publish on the server.
Using ReactiveVar we can get subscription is ready or not.
Template.myTemplate.onCreated(function(){
this.isSubscriptionReady = new ReactiveVar(false);
});
Template.myTemplate.helpers({
settings: function () {
return {
collection: collection,
rowsPerPage: 10,
showFilter: true,
fields: ['name', 'location', 'year'],
ready: Template.instance().isSubscriptionReady
};
},
isSubscriptionReady: function () {
return Template.instance().isSubscriptionReady.get();
}
});

How do you do client side routing when saving via methods?

I want to save some data and show it in a view template. So I want to do like the example below but using methods.
Template.postSubmit.events({
'submit form': function(e) {
e.preventDefault();
var post = {
url: $(e.target).find('[name=url]').val(),
title: $(e.target).find('[name=title]').val()
};
post._id = Posts.insert(post);
Router.go('postPage', post);
}
});
I tried this:
'insertClubData': function(clubname, capacity, description, homepage){
var currentUserId = Meteor.userId();
var club = {
clubname: clubname,
description: description,
capacity: parseInt(capacity),
homepage: homepage,
createdAt: new Date(),
visitors: 0,
occupancy: 0,
trend: "club-1",
createdBy: currentUserId
}
club._id = clubs.insert(club);
Router.go('club', club);
},
but I get the error:
Exception while invoking method 'insertClubData' TypeError: Object
function router(req, res, next) { I20160425-14:04:55.724(2)? //XXX
this assumes no other routers on the parent stack which we should
probably fix
I understand that this is because Router.go is a client side method. But I also understand that you should avoid server side routing. So what's the most elegant solution?
This is my route:
Router.route('/club/:_id', {
name: 'club',
template: 'club',
data: function(){
return clubs.findOne({_id: this.params._id})
}
});
How about, you call the method from the client and in the callback on success you do the routing. For example:
Template.postSubmit.events({
'submit form': function(e) {
e.preventDefault();
var post = {
url: $(e.target).find('[name=url]').val(),
title: $(e.target).find('[name=title]').val()
};
Meteor.call('insertPost', post, function(error, id) {
if (error) {
alert(error)
} else {
Router.go('postPage', {_id: id});
}
});
}
});
and on the server
Meteor.methods({
insertPost: function(post) {
// do checks
id = Posts.insert(post);
return id;
}
});
Does that work for you?

Meteor pub/sub issues

This below is my collection code
Competitions = new Mongo.Collection("competitions");
var CompetitionsSchema = new SimpleSchema({
year: {
type: String
},
division: {
type : String,
allowedValues: ['Elite', '1st','2nd','3rd','4th','Intro']
},
teams:{
type : [TeamSchema],
allowedValues: (function () {
return Teams.find().fetch().map(function (doc) {
return doc.name;
});
}()) //here we wrap the function as expression and invoke it
}
});
In the allowedValues function
Teams.find is empty.
In the router I am subscribing to the publication as follows
this.route('competitions', {
path: '/admin/competitions',
layoutTemplate: 'adminLayout',
waitOn: function () {
return [
Meteor.subscribe('teams')
];
}
});
This is my publish function
Meteor.publish('teams', function() {
return Teams.find({},{sort: {
points: -1,
netRunRate : -1
}});
});
Do I have to do subscription some where else as well?
Your problem is in this piece of code:
allowedValues: (function () {
return Teams.find().fetch().map(function (doc) {
return doc.name;
});
}()) //here we wrap the function as expression and invoke it
This gets called when the page loads. At that point the Teams collection will still be empty on the client side. You need to wait until the data is ready. Since you are using waitOn in iron-router, it might be enough to just move this code to the onRendered callback.

Meteor.js calling a template.helpers function vs global variable

I am using Reactive-table to display paginated data in my meteor.js app as shown below, yet data displayed in Reactive-table is dependent on on specific user event (Selecting client, project, date range and clicking on the submit button). So I was wondering if it is possible to trigger template.helpers >> myCollection function from the 'submit form' event? OR is it better to define a global variable to store data returned from user query based on the user (client, project, date range selection) then make this global variable the return from the myCollection function?
I have tried researching how to call .helpers function from an template.events event but couldn't find any information. So any help on which approach is better and if calling the .events function is better then how to do that, will be highly appreciated. Thanks.
Below is the code I have in my app:
Template.detailedreport.rendered = function() {
Session.set("dreport_customer", "");
Session.set("dreport_project", "");
Session.set("dreport_startDate", new Date());
Session.set("dreport_endDate", new Date());
$('.set-start-date').datetimepicker({
pickTime: false,
defaultDate: new Date()
});
$('.set-end-date').datetimepicker({
pickTime: false,
defaultDate: new Date()
});
$('.set-start-date').on("dp.change",function (e) {
Session.set("dreport_startDate", $('.set-start-date').data('DateTimePicker').getDate().toLocaleString());
});
$('.set-end-date').on("dp.change",function (e) {
Session.set("dreport_endDate", $('.set-end-date').data('DateTimePicker').getDate().toLocaleString());
});
};
Template.detailedreport.helpers({
customerslist: function() {
return Customers.find({}, {sort:{name: -1}});
},
projectslist: function() {
return Projects.find({customerid: Session.get("dreport_customer")}, {sort:{title: -1}});
},
myCollection: function () {
var now = Session.get("dreport_startDate");
var then = Session.get("dreport_endDate");
var custID = Session.get("dreport_customer");
var projID = Session.get("dreport_project");
Meteor.call('logSummary', now, then, projID, custID, function(error, data){
if(error)
return alert(error.reason);
return data;
});
}
},
settings: function () {
return {
rowsPerPage: 10,
showFilter: true,
showColumnToggles: false,
fields: [
{ key: '0._id.day', label: 'Day' },
{ key: '0.totalhours', label: 'Hours Spent'}
]
};
}
});
Template.detailedreport.events({
'submit form': function(e) {
e.preventDefault();
var now = $('.set-start-date').data('DateTimePicker').getDate().toLocaleString();
var then = $('.set-end-date').data('DateTimePicker').getDate().toLocaleString();
var custID = $(e.target).find('[name=customer]').val();
var projID = $(e.target).find('[name=project]').val();
//Here is the problem as I am not sure how to refresh myCollection function in .helpers
},
'change #customer': function(e){
Session.set("dreport_project", "");
Session.set("dreport_customer", e.currentTarget.value);
},
'change #project': function(e){
Session.set("dreport_project", e.currentTarget.value);
}
});
Template:
<div>
{{> reactiveTable class="table table-bordered table-hover" collection=myCollection settings=settings}}
</div>
Server:
Meteor.methods({
logSummary: function(startDate, endDate, projid, custid){
//Left without filtering based on date, proj, cust for testing only...
return Storylog.find({});
}
});
Template helpers are reactive, meaning that they will be recomputed if their dependencies change. So all you need to do is update their dependencies and then the myCollection helper will be recomputed.
Replace your comment // Here is the problem... with:
Session.set('dreport_endDate', then);
Session.set('dreport_startDate', now);
Session.set('dreport_project', projID);
Session.set('dreport_customer', custID);

Backbone Collection Fetch() doesnt work

I have a jquery mobile based implementation of a mobile website and now learning backbone.js and rethinking the app to better organize it.
var membership = Backbone.Model.extend();
var memberships = Backbone.Collection.extend({
model: membership,
parse: function (resp, xhr) {
},
url: "/groups.svc/memberships/azxcv01"
});
var col1 = new memberships();
col1.fetch({ success: function () {
console.log(col1);
}
});
In chrome, I see that the URL is formatted well and returns valid JSON back. The parse() event also gets a valid resp. But the console.log() above displays and empty array "[ ]".
What am I missing ?
try this,
here link to fiddle http://jsfiddle.net/w7xeb/ (updated)
var membership = Backbone.Model.extend();
var memberships = Backbone.Collection.extend({
model: membership,
parse: function (resp, xhr) {
return resp;
},
});
var col1 = new memberships();
col1.fetch({
url : "/restful/fortune",
success: function () {
console.log(col1);
}
});
​
response
$.mockjax({
url: "/restful/fortune",
responseTime: 750,
contentType: "text/json",
responseText: [{
a:'a'
},{
a:'b'
},{
a:'c'
}]
});

Resources