How do I send a POST request with all parameters from a form using an AngularJS directive?

I have made an AngularJS form that integrates Stripe thru a directive. Fiddle here:


<body ng-app="angularjs-starter">
  <script src=""></script>
  <div ng-controller="MainCtrl">
    <form name="regForm" id="register-form">
      <input ng-model="" type="email" name="username">
      <div stripe-validator 
      <button ng-model="reg.btn" ng-disabled="stripeCompleted === false || !regForm.username.$valid">Register</button>


var app = angular.module('angularjs-starter', []);

app.controller('MainCtrl', function($scope, $rootScope) {
  //Init stripe state via controller
  $scope.stripeCompleted = false;

app.directive('stripeValidator', function() {
  return {
    restrict: 'A',
    template: `
      <div id="stripe-wrapper">
        <div id="card-element"></div>
      <small id="card-errors" class="text-danger" role="alert">{{ ccErrMsg }}</small>
      <input type="hidden" name="stripeToken" ng-value="stripeToken" />`,
    scope: {
      "stripeComplete": '=',
      "stripeFormId": '@',
      "stripeError": '=',
      "stripeToken": '=',
    link: function(scope, element, attrs) {

      var stripe = Stripe("pk_test_6pRNASCoBOKtIshFeQd4XMUh");
      var elements = stripe.elements();
      var card = elements.create("card");
      var form = document.getElementById(scope.stripeFormId);

      //mount card element

      //add event listener
      card.addEventListener('change', function(event) {

        //check for errors
        if (event.error) {
          scope.ccErrMsg = event.error.message;
        } else {
          scope.ccErrMsg = '';

        //check for complete
        scope.stripeComplete = event.complete ? true : false;

        //apply scope

      //inject form submit event
      form.addEventListener("submit", function(event) {

        //prevent form submit

        //handle token, handle error and form submit forward
        stripe.createToken(card).then(function(result) {

          if (result.error) {
             scope.ccErrMsg = event.error.message;
             scope.stripeToken = '';
          } else {
             scope.ccErrMsg = '';
             scope.stripeToken = result.token;

          //apply scope

          //forward submit

Instead of using form.submit(), I want to use $ to send the form parameters and data to my backend, then send back any data from there in a .then() function. In this case, the parameters include's value.

How do I do this with the way my form is set up? I'd prefer using ng-submit, but if that's not possible, is there another way?



I would suggest using a component to wrap the stripe input. You can make this component work with the ng-model directive to pass the card element back to the parent scope as well as apply form validation to the stripe field.

TL;DR - Here's an example Fiddle

First thing you'll want to do is create your stripe object as a service so it can be shared.

app.service('stripe', function () {
    return Stripe("pk_test_6pRNASCoBOKtIshFeQd4XMUh");

Then you can implement the stripe component to wrap around the stripe input and apply custom ng-model validation.

app.component('stripe', {
    bindings: {
        state: '='
    require: {
        model: 'ngModel'
    controller: function ($element, $timeout, stripe) {
        this.$onInit = function () {
            var ctrl = this;

            // stripe is passed in to controller as a service
            var elements = stripe.elements();
            var card = elements.create('card');

            card.addEventListener('change', function (event) {
                // Attach the event as the state so it is visible
                // to consumers of the stripe component.
                ctrl.state = event;

                // Set the validity of the stripe on the ng-model
                ctrl.model.$setValidity('stripe', event.complete);

                // If the stripe is complete set the card element on 
                // the ng-model, otherwise null out the model value.
                if (event.complete) {
                } else {

Then in the main controller you can create the stripe token when the form is submitted before you send off the HTTP request.

app.controller('MainCtrl', function ($scope, $http, stripe) {
    $scope.reg = {};
    $scope.onChange = function() {
    $scope.register = function () {
        // Create the stripe token and send the registration
        stripe.createToken($scope.card).then(function (result) {
            if (result.error) {
            } else {
                $scope.reg.stripeToken = result.token;
                $'request-url', $scope.reg).then(function (response) {
                }).catch(function (err) {

Now you can simply add a stripe element to your template as follows:

<div ng-app="angularjs-starter" ng-controller="MainCtrl">
  <form name="regForm" id="register-form" ng-submit="register()">
    <stripe name="card" ng-model="card" state="cardState" ng-change="onChange()" ng-required="true"></stripe>
    <button ng-disabled="regForm.$invalid">Register</button>
    <span ng-if="regForm.card.$invalid">{{ cardState.error.message }}</span>


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.