Meteor pass data from client to server - javascript

I have a registration form, and when the user clicks the submit button the value in every textbox will be sent to server to insert that data, and return true/false.
Client:
Template.cust_register.events({
'click button': function(){
var email = $('#tbxCustEmail').val();
var msg = $('#tbxCustMsg').val();
var isSuccess = insertMsg(email,msg);
if(isSuccess){
alert("Success");
}else alert("Try again");
}
});
Server:
function insertMsg(email,msg){
Messages.insert({Email:email,Message:msg});
return true;
}
This turned out to not work.
How to solve this?
Many people said "use publish/subscribe", but I don't understand how to use that.

First, watch the introductory screencast and read the Data and security section of the docs.
Your code in a publish/subscribe model would look like this:
Common:
Messages = new Meteor.Collection('messages');
Client:
Meteor.subscribe("messages");
Template.cust_register.events({
'click button': function(){
var email = $('#tbxCustEmail').val();
var msg = $('#tbxCustMsg').val();
Messages.insert({Email:email,Message:msg});
}
});
Server:
Meteor.publish("messages", function() {
return Messages.find();
});

An alternative solution is to use Meteor.call('yourMethodName') (on the client).
Then, on the server, you can have
Meteor.methods({
yourMethodName: function() { /* validate input + return some data */ }
});
You can consider setting a session variable to the return value.
Meteor.call('yourMethodName', function (err, data) {
if (!err) {
Session.set('myData', data);
}
});
And then in some some template...
Template.whatever.helpers({
messages: function() {
return Session.get('myData');
}
});
Why do all this?
1) You can explicitly deny all direct `insert/update/find` queries from the client, and force usage of pre-defined Meteor methods.
2) You can manually determine when certain data is "refreshed".
Obviously, this methodology undermines the value of the subscription/publication model, and it should only be used in cases where real-time data isn't required.

Related

Meteor change database at run time

I have three database i.e, main_db it is default load database. I want load database after login.
Database are:-
main_db
->user_collection
psm_2017_db
->abc_collection
->xyz_collection
psm_2018_db
->abc_collection
->xyz_collection
Here is my project structure
here is my login script.
client
|->login
|->login.js
Template.login.rendered = function(){
SessionStore.set("login_user",false);
};
Template.login.events({
'submit #formLogin': function (event, target){
event.preventDefault();
var email = target.find('#loginEmail').value;
var password = target.find('#loginPassword').value;
// console.log(email +" "+password);
Meteor.loginWithPassword(email, password, function(err){
if(err){
console.log(err);
alert("Invalid Login!");
}
else {
SessionStore.set("login_user",true);
console.log('successfully')
Router.go("/dashboard")
}
});
}
});
Template.layout.helpers({
"isLoggedin": function () {
return SessionStore.get("login_user");
}
});
here is my load collection file
lib
|->collection.js
abcCollection=new Mongo.Collection("abc_collection");
xyzCollection=new Mongo.Collection("xyz_collection");
You can connect to multiple dbs using the below approach.
var database = new MongoInternals.RemoteCollectionDriver("<<mongo url>>");
MyCollection = new Mongo.Collection("collection_name", { _driver: database });
<<mongo_url>> is your standard mongodb url.
Eg. mongodb://127.0.0.1:27017/database_name
Now, in your specific scenario, main_db contains the user collection (I'm under the assumption that this is pertaining to meteor user collection). You need to have this loaded at all times. You can't have it load after login since user information - which is required for logging in resides in that db!
Once you take care of the above, connecting to the remaining two dbs can be done on login as below:
/lib/dbconnection.js (this will be common to both server and clinet)
Meteor.methods({
loadDB: function(){
if(Meteor.userId()){ // if a user has logged in
var database = new MongoInternals.RemoteCollectionDriver("<<mongo url>>");
MyCollection = new Mongo.Collection("collection_name", { _driver: database });
}
}
})
Meteor.call("loadDB");
loadDB will get called each time a user logs in. But I fear that it will be run each time any user logs in. In order to avoid it being re-initialized for each user login, you might want to do a check on whether database or myCollection already exists.

How to insert data in ground.db in meteor when offline

i have a fully working meteor application but now i want to make it offline so I installed ground:db and appcache here is my package file:
...
ground:db
appcache
ground:localstorage
then I changed my Collections to this:
Gebiete = new Mongo.Collection('gebiete');
Straßen = new Mongo.Collection('straßen');
Nummern = new Mongo.Collection('nummern');
Ground.Collection(Gebiete);
Ground.Collection(Straßen);
Ground.Collection(Nummern);
and now when the app is online i can insert data and then i disconnect the app and relaunch (cordova) and no data is lost.
But when im offline and i want to insert sth. it doesnt work ;(. I thaught i dont have to change my methods file but here is one method just to make sure if it is right:
Meteor.methods({
neuesGebiet(Besitzer, Gebietsname, Gebietsnummer, Ort, Erstellungsdatum) {
Gebiete.insert({
Besitzer: Besitzer,
Gebietsname: Gebietsname,
Gebietsnummer: Gebietsnummer,
Ort: Ort,
Erstellungsdatum: Erstellungsdatum
});
}
});
and on the client the message is called like this:
import { Meteor } from 'meteor/meteor'
Template.neuesGebietErstellen.onCreated(function () {
this.subscribe('gebiete');
});
Template.neuesGebietErstellen.events({
"submit .add-Gebiet": function (event) {
var Gebietsname = event.target.Gebietsname.value;
var Gebietsnummer = event.target.Gebietsnummer.value;
var Ort = event.target.Ort.value;
var Besitzer = Meteor.userId();
var Erstellungsdatum = new Date();
var Datum = Erstellungsdatum.toLocaleDateString();
Meteor.call('neuesGebiet', Besitzer, Gebietsname, Gebietsnummer, Ort, Datum)
FlowRouter.go('/');
return false;
}
});
Please help me to get the data inserted when offline because i want it to be 100% offline
Thank you ;)
It's been a while since I used Ground:db but here's what I think you are missing...
First, you probably only want grounded collections on Cordova, so
if(Meteor.isCordova) {
Ground.Collection(Gebiete);
Ground.Collection(Straßen);
Ground.Collection(Nummern);
}
Then you need to use Groundmethods to store your method calls. So after the definition of the method:
Meteor.methods({
'neuesGebiet': function(...) {
...
}
});
if( Meteor.isClient ) {
Ground.methodResume([
'neuesGebiet'
]);
}

AngularJS and Stripe: Send token to server, insert the token into the form

I am working on a card processing API with ASP.NET , HTML , AngularJS and Stripe.NET. I am pretty new to all of them.
I followed the documentation on the Stripe website for sending the Stripe token to the server (here): https://stripe.com/docs/stripe.js#card-validateCardNumber
It worked! However, instead of JQuery I want to use AngularJS. I want to convert from JQuery to AngularJS this part of the JQuery code:
Stripe.card.createToken({
number: $('.card-number').val(),
cvc: $('.card-cvc').val(),
exp_month: $('.card-expiry-month').val(),
exp_year: $('.card-expiry-year').val(),
address_zip: $('.address_zip').val()
}, stripeResponseHandler);
function stripeResponseHandler(status, response) {
// Grab the form:
var $form = $('#payment-form');
if (response.error) { // Problem!
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('button').prop('disabled', false); // Re-enable submission
} else { // Token was created!
// Get the token ID:
var token = response.id;
// Insert the token into the form so it gets submitted to the server:
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
// Submit the form:
$form.get(0).submit();
}
}
If someone can help, I will appreciate it a lot. Thanks. :)
I was able to answer my question (a while ago, just finding some time to answer it in here).
Firstly, here are the tips:
Use "angular-payments.js". You can find it here: https://github.com/laurihy/angular-payments
You have to use the html syntax for the card details as in the documentation of the repository.
It is not the same as in the Stripe documentation. I have used AngularJS service so that I can pass my token to my ASP.NET application.
Thirdly, I had problems with the verification token - here is a nice post for how to handle it: http://blog.novanet.no/anti-forgery-tokens-using-mvc-web-api-and-angularjs/
Here is (part of) my (AngularJS) code:
(function () {
var app = angular.module("myApp", ["angularPayments"]);
app.service('Service', function ($http) {
this.AddCard = function (stripeToken, stripeEmail) {
var tokenData = {
"stripeToken": stripeToken,
"stripeEmail": stripeEmail
};
$http.post("http://localhost:48484/payment/card", tokenData).success(function (response) {
window.location = '/cardprocess/confirmation';
})
};
});
app.directive('ncgRequestVerificationToken', ['$http', function ($http) {
return function (scope, element, attrs) {
$http.defaults.headers.common['RequestVerificationToken'] = attrs.ncgRequestVerificationToken || "no request verification token";
};
}]);
app.controller("myCtrl", ['$scope', myCtrl]);
app.controller("buyCtrl", function ($scope, CardService) {
$scope.submit = function () {
$scope.processing = true;
}
$scope.stripeFormSubmit = function (code, result) {
$scope.processing = false;
$scope.hideAlerts();
if (result.error) {
$scope.stripeError = result.error.message;
} else {
//$scope.stripeToken = result.id;
$scope.stripeToken = result.id;
CardService.AddCard($scope.stripeToken, $scope.stripeEmail);
}
};
$scope.hideAlerts = function () {
$scope.stripeError = null;
$scope.stripeToken = null;
};
});
}());
(The html page is quite big so I decided not to put in here. It should be straight forward - I have a form, which calls AngularJS model "stripeFormSubmit".)
Finally, you can see the "CardService", which is talking to my api - the service is initialised at the begining of the paste code.
That is the main idea. I decided not to go in a lot of detail. But I will try to answer questions (if any).

Trying to pass <%> HTML Variable to Javascript - Node, Passport, and Stripe

A bit of a newbie here. I've been looking for an answer that works and found some similarities in a Jade problem but I'm not using Jade. I have passed an "user" attribute into an HTML view as so:
app.get('/profile', isLoggedIn, function(req, res) {
res.render('profilePage/profilePage.html', {
user : req.user // get the user out of session and pass to template
});
});
Then, in my profile HTML, I can access my user property like so:
<%=user.local.firstname%>'s Profile
However, I want to allow Stripe to send the user's credit card info via the Stripetoken. I have managed to include a variable amount from a text field the user inputs. However, I want to append the user property so I can use it in my callback. Here is the javascript/jquery that's included in the profile html:
<!-- New section -->
<script type="text/javascript">
<!-- Fill in your publishable key -->
Stripe.setPublishableKey('pkkey');
var stripeResponseHandler = function(status, response) {
var $form = $('#contactForm');
var $amount = $('#amount').val();
if (response.error) {
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('button').prop('disabled', false);
} else {
// token contains id, last4, and card type
var token = response.id;
// Insert the token into the form so it gets submitted to the server
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
$form.append($('<input type="hidden" name="amount" />').val($amount));
// and re-submit
$form.get(0).submit();
}
};
jQuery(function($) {
$('#contactForm').submit(function(e) {
var $form = $(this);
// Disable the submit button to prevent repeated clicks
$form.find('button').prop('disabled', true);
Stripe.card.createToken($form, stripeResponseHandler);
// Prevent the form from submitting with the default action
return false;
});
});
</script>
As you can see, I have managed to append the $amount variable so I can access it in the callback:
module.exports = function(app, passport) {
app.post('/stripe', function(req,res) {
// =====STRIPETOKEN======
var transaction = req.body;
var stripeToken = transaction.stripeToken;
var donationAmount = transaction.amount;
stripe.customers.create({
source : stripeToken,
account_balance : 0
},function(err, customer) {
if (err) {
console.log(err);
} else {
console.log("Success!");
}});
// ====CREATE CHARGE======
var charge =
{
amount : donationAmount,
currency : 'USD',
card : stripeToken
};
stripe.charges.create(charge, function(err, charge) {
if(err)
console.log(err);
else
{
res.json(charge);
console.log('Successful charge sent to Stripe!');
console.log(charge);
};
});
// ====PROFILE PAGE REDIRECT=====
res.render('profilePage/profilePage.html', {
});
});
So here's my problem. I want to pass the user's information, kind of like I did the amount, into the post method so when it redirects on success, I can pass it back in the res.render function, as well as send it to Stripe for description purposes. The only thing I can think of is to put the user info in a hidden field in HTML and access it like that, but that sounds messy and not proper.
This is my first time posting here so I apologize if it was too lengthy or not specific enough. Thanks!
The answer was in the way I was declaring passport and stripe in my application. Make sure you declare passport after everything to make the user variable available to stripe and all views.

Node/Javascript: Redirect After Verification Button

I'm using a framework called PartialJS that follows a MVC architecture to build a webApp that will verify a user's input and make a request to an API and render the API response.
I'm not sure how to redirect the user to the rendered page after verification and API call has finished. Where should the page redirect and API calls be made?
Here's a quick breakdown of what the user will see with 'bullet' marks denoting what happens in the backend:
User presented with a form and fills information
exports.onValidation() called via a serialized JSON to verify that
all fields completed accurately (triggered by a button), done without
a page refresh.
API call is made with user's information, will not return until response is received and parsed
Form rendered with decoded JSON response from external API
I have tried using this in the 'view.html' page but the page redirects before verification.
<buttononclick="window.location='http://www.CaliCoder.com/results';">Submit</button>
<script type="text/javascript">
$(document).ready(function() {
$('button').bind('click', function() {
$.post('/', $('#f').serialize(), function(d) {
var err = $('#error');
if (d instanceof Array) {
err.empty();
d.forEach(function(o) {
err.append('<div>' + o.error + '</div>');
});
err.show();
return;
};
$('#f').trigger('reset');
err.empty();
err.show().html('SUCCESS! Please wait while the request is being made')
});
});
});
</script>
Here's what happens in the 'controller.js' end of things.
function json_form() {
var self = this;
var error = self.validate(self.post, ['intersection', 'hours', 'minutes', 'phone'])
if (error.hasError()) {
self.json(error);
return;
}
// save to database
var db = self.database('forms');
db.insert(self.post);
self.json({ r: true });
}
function get_routes(hours, minutes, intersection) {
//The following code makes a call that returns an array with data to be rendered by another view controller.
var stops = this.module('cumtd').GetStopsBySearch('springfied busey');
}
Thanks for reading! Sorry for sounding confusing, I'm new to JS and Node programming. :(
You have problem in clide-side JavaScript, solution:
HTML:
<button>Submit</button>
JavaScript:
$(document).ready(function() {
$('button').bind('click', function() {
$.post('/', $('#f').serialize(), function(d) {
var err = $('#error');
if (d instanceof Array) {
err.empty();
d.forEach(function(o) {
err.append('<div>' + o.error + '</div>');
});
err.show();
return;
};
$('#f').trigger('reset');
err.empty();
err.show().html('SUCCESS! Please wait while the request is being made');
// HERE REDIRECT:
setTimeout(function() {
window.location.href = 'http://www.CaliCoder.com/results';
}, 3000);
});
});
});

Categories

Resources