angular-forms
Javascript

Submitting AJAX Forms: The AngularJS Way

A lot of developers were submitting forms before AngularJS came out. There were so many different ways to submit forms that it could drive a person crazy… and they still can.

Today we’ll be looking at a simple form that used to be submitted using PHP and how to convert that to Angular. Using Angular for forms was one of those AHA moments for me. Even though it barely scratches the surface of Angular, it helps a user see the potential after seeing forms submitted and understanding the idea of two-way data-binding.

We will look at processing a form with just plain jQuery. The work needed to do this will be primarily in the javascript. We will submit the form, show errors, add error classes, and show/hide messages in javascript.

After that, we will be using Angular. The bulk of the work that was needed before will go away and lots of the things we did before (showing errors, adding classes, showing/hiding messages) will be so much simpler. Let’s dive in.

Submitting Forms with Just jQuery and AJAX: If you want to view a full article on submitting a form just using jQuery and AJAX, view our other article: Submitting AJAX Forms with jQuery.

Our Sample Form

We’ll be looking at two ways to submit this form:

  • The Old Way: AJAX Form with jQuery and PHP
  • The New Way: AJAX Form with AngularJS and PHP

Take a look at what we’ll be building. Super simple.

submitting-forms-with-angular

Form Requirements

  • Process the form without page refresh
  • Enter Name and Superhero Alias
  • Show errors if there are any
  • Turn inputs red if there are errors
  • Show success message if all is good

File Structure

We’ll only need two files to demonstrate.

  • index.html
  • process.php

Processing the Form

Let’s setup the PHP to process our form. This will be very minimal and will use http POST to get the form data.

Processing the Form: This won’t be that important to us. You can use any other language to process your form that you like.
// process.php

<?php

$errors         = array();  	// array to hold validation errors
$data 			= array(); 		// array to pass back data

// validate the variables ======================================================
	if (empty($_POST['name']))
		$errors['name'] = 'Name is required.';

	if (empty($_POST['superheroAlias']))
		$errors['superheroAlias'] = 'Superhero alias is required.';

// return a response ===========================================================

	// response if there are errors
	if ( ! empty($errors)) {

		// if there are items in our errors array, return those errors
		$data['success'] = false;
		$data['errors']  = $errors;
	} else {

		// if there are no errors, return a message
		$data['success'] = true;
		$data['message'] = 'Success!';
	}

	// return all our data to an AJAX call
	echo json_encode($data);

This is a very simple form processing script. We will just check if the data exists. If it does exist, don’t do anything. If it doesn’t exist, add a message to our $errors array.

To return our data to an AJAX call, we have to echo and json_encode. This is all we have to do with our PHP form processing. It will be the same for processing a form using normal jQuery AJAX or Angular.

Showing the Form

Let’s create our HTML that will show our form.

<!-- index.html -->

<!doctype html>
<html>
<head>
	<title>Angular Forms</title>

	<!-- LOAD BOOTSTRAP CSS -->
	<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">

	<!-- LOAD JQUERY -->
        <!-- when building an angular app, you generally DO NOT want to use jquery -->
        <!-- we are breaking this rule here because jQuery's $.param will help us send data to our PHP script so that PHP can recognize it -->
        <!-- this is jQuery's only use. avoid it in Angular apps and if anyone has tips on how to send data to a PHP script w/o jQuery, please state it in the comments -->
   	<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

	<!-- PROCESS FORM WITH AJAX (OLD) -->
	<script>
		<!-- WE WILL PROCESS OUR FORM HERE -->
	</script>
</head>
<body>
<div class="container">
<div class="col-md-6 col-md-offset-3">

	<!-- PAGE TITLE -->
	<div class="page-header">
		<h1><span class="glyphicon glyphicon-tower"></span> Submitting Forms with Angular</h1>
	</div>

	<!-- SHOW ERROR/SUCCESS MESSAGES -->
	<div id="messages"></div>

	<!-- FORM -->
	<form>
		<!-- NAME -->
		<div id="name-group" class="form-group">
			<label>Name</label>
			<input type="text" name="name" class="form-control" placeholder="Bruce Wayne">
			<span class="help-block"></span>
		</div>

		<!-- SUPERHERO NAME -->
		<div id="superhero-group" class="form-group">
			<label>Superhero Alias</label>
			<input type="text" name="superheroAlias" class="form-control" placeholder="Caped Crusader">
			<span class="help-block"></span>
		</div>

		<!-- SUBMIT BUTTON -->
		<button type="submit" class="btn btn-success btn-lg btn-block">
			<span class="glyphicon glyphicon-flash"></span> Submit!
		</button>
	</form>

</div>
</div>
</body>
</html>

Now we have our form. We’ve also used Bootstrap to make it not super ugly. Using the Bootstrap syntax, there is also a spot under each input to show a line of text for our errors.

submitting-forms-with-angular

Submit the Form with jQuery

Let’s go through the process of submitting the form with jQuery now. We will add all the code into our empty <script> tags.

<!-- index.html -->

...

	<!-- PROCESS FORM WITH AJAX (OLD) -->
	<script>
		$(document).ready(function() {

			// process the form
			$('form').submit(function(event) {

				// remove the past errors
				$('#name-group').removeClass('has-error');
				$('#name-group .help-block').empty();
				$('#superhero-group').removeClass('has-error');
				$('#superhero-group .help-block').empty();

				// remove success messages
				$('#messages').removeClass('alert alert-success').empty();

				// get the form data
				var formData = {
					'name' 				: $('input[name=name]').val(),
					'superheroAlias' 	: $('input[name=superheroAlias]').val()
				};

				// process the form
				$.ajax({
					type 		: 'POST',
					url 		: 'process.php',
					data 		: formData,
					dataType 	: 'json',
					success 	: function(data) {

						// log data to the console so we can see
						console.log(data);

						// if validation fails
						// add the error class to show a red input
						// add the error message to the help block under the input
						if ( ! data.success) {

							if (data.errors.name) {
								$('#name-group').addClass('has-error');
								$('#name-group .help-block').html(data.errors.name);
							}

							if (data.errors.superheroAlias) {
								$('#superhero-group').addClass('has-error');
								$('#superhero-group .help-block').html(data.errors.superheroAlias);
							}

						} else {

							// if validation is good add success message
							$('#messages').addClass('alert alert-success').append('<p>' + data.message + '</p>');
						}
					}
				});

				// stop the form from submitting and refreshing
				event.preventDefault();
			});

		});
	</script>

...


There’s a lot of code here to process the form. We have code to get the variables from the form, send it to our form using AJAX, check if there are any errors, and show a success message. On top of all that, every time the form is submitted, we want it to clear the past errors. Quite a lot of code.

Now if there is an error:

submitting-error

Or if there is a successful submission:

submit-success

Now let’s look at the same form, submitted with Angular. Remember, we don’t have to change anything about how our PHP processes the form and our application will function the same (showing errors and successes in the same places).

Submit the Form with Angular

We are going to set up our Angular application right inside the <script> tags we used earlier. So just delete everything inside and let’s begin.

Setting Up An Angular Application

The steps to set up our Angular application are:

  1. Load angular
  2. Set up a module
  3. Set up controller
  4. Apply module and controller to HTML
  5. Set up 2-way bound variables
  6. Set up errors and messages

It sounds like a lot, but in the end, we’ll use far less code and it will be much cleaner. It will also be much easier to create larger forms with many more inputs.

Angular Module and Controller

Let’s load up Angular and create our module and controller.

<!-- index.html -->

...

	<!-- LOAD JQUERY -->
	<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
	<!-- LOAD ANGULAR -->
	<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>

	<!-- PROCESS FORM WITH AJAX (NEW) -->
	<script>

		// define angular module/app
		var formApp = angular.module('formApp', []);

		// create angular controller and pass in $scope and $http
		function formController($scope, $http) {

		}

	</script>
</head>

<!-- apply the module and controller to our body so angular is applied to that -->
<body ng-app="formApp" ng-controller="formController">

...


We now have the foundation for our Angular app. We’ve loaded Angular, created a module and controller, and applied it to our site.

Next we will be showing off how 2-way binding works.

2-Way Data-Binding

This is one of the core ideas of Angular and one of its most powerful. From the Angular docs: “Data-binding in Angular web apps is the automatic synchronization of data between the model and view.” This means that the step where we have to grab data from the form using $('input[name=name]').val() is not required.

We bind data to a variable in Angular, and whenever it changes in either the Javascript or in the view, it changes in both.

To demonstrate data-binding, we’ll get our form inputs to populate a variable formData automagically. Let’s look back at our Angular controller that we applied to our page. We passed in $scope and $http.

$scope: The glue between application controller and the view. Basically variables are passed to and from our controller and view using $scope. For a more detailed definition, check out the docs.
$http: The Angular service that will help us do our POST request. For more information, check out the docs.

Getting the Variables Using Data-Binding

Alright, enough talk. Let’s apply this information to our form. It’s way simpler than it sounded above. We will add a line to the Angular controller and a line to the view.

<!-- index.html -->

...

	<!-- PROCESS FORM WITH AJAX (NEW) -->
	<script>

		// define angular module/app
		var formApp = angular.module('formApp', []);

		// create angular controller and pass in $scope and $http
		function formController($scope, $http) {

			// create a blank object to hold our form information
			// $scope will allow this to pass between controller and view
			$scope.formData = {};

		}

...


Now we have set up a formData object. Let’s populate it with our form inputs. Before we had to explicitly call each input and get its val(). Not anymore. We will use ng-model to bind a specific input to a variable.

<!-- index.html -->

...

	<!-- FORM -->
	<form>
		<!-- NAME -->
		<div id="name-group" class="form-group">
			<label>Name</label>
			<input type="text" name="name" class="form-control" placeholder="Bruce Wayne" ng-model="formData.name">
			<span class="help-block"></span>
		</div>

		<!-- SUPERHERO NAME -->
		<div id="superhero-group" class="form-group">
			<label>Superhero Alias</label>
			<input type="text" name="superheroAlias" class="form-control" placeholder="Caped Crusader" ng-model="formData.superheroAlias">
			<span class="help-block"></span>
		</div>

		<!-- SUBMIT BUTTON -->
		<button type="submit" class="btn btn-success btn-lg btn-block">
			<span class="glyphicon glyphicon-flash"></span> Submit!
		</button>
	</form>

	<!-- SHOW DATA FROM INPUTS AS THEY ARE BEING TYPED -->
	<pre>
		{{ formData }}
	</pre>

...


Now, Angular will now that each input is bound to formData. As you type into each input box, you can see the formData object being populated! It’s magic!

You do not need to use the word $scope in the view. Everything is considered to be nested inside of $scope.

Processing the Form

In our old form, we had to use jQuery to submit the form using $('form').submit(). Now we will use an Angular feature called ng-submit. To do this, we will add a controller function to process the form, and tell our form to use that controller function..

<!-- index.html -->

...

	<!-- PROCESS FORM WITH AJAX (NEW) -->
	<script>

		// define angular module/app
		var formApp = angular.module('formApp', []);

		// create angular controller and pass in $scope and $http
		function formController($scope, $http) {

			// create a blank object to hold our form information
			// $scope will allow this to pass between controller and view
			$scope.formData = {};

			// process the form
			$scope.processForm = function() {

			};

		}

...

	<!-- FORM -->
	<form ng-submit="processForm()">

...


Now our form knows to use that controller function when it is submitted. Now that we have that in place, let’s actually process the form using $http.

The syntax for processing a form will look very similar to the original way of doing it. The benefit is that we don’t have to grab our form data manually, or inject, hide, or add classes to show errors or success messages.

<!-- index.html -->

...

// process the form
$scope.processForm = function() {
	$http({
        method  : 'POST',
        url     : 'process.php',
        data    : $.param($scope.formData),  // pass in data as strings
        headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  // set the headers so angular passing info as form data (not request payload)
    })
        .success(function(data) {
            console.log(data);

            if (!data.success) {
            	// if not successful, bind errors to error variables
                $scope.errorName = data.errors.name;
                $scope.errorSuperhero = data.errors.superheroAlias;
            } else {
            	// if successful, bind success message to message
                $scope.message = data.message;
            }
        });
};

...


That’s it for our form! None of that adding or removing classes. We don’t have to clear the errors every time we submit the form. We just have to bind the variables and the view will take care of the rest. This is great since the controller is for the data and the view is for showing the data.

jQuery POST vs Angular POST Sometimes you may see that your POST isn’t showing data on the server. This is because of the difference in the way jQuery and Angular serialize and send data. This comes down to the server language you are using and its ability to understand Angular’s data.

The above code is for a PHP server and jQuery is needed for the $.param function. There are ways to do it without jQuery but that’s pretty much the only reason jQuery was included for this example. Because it was easier.

The below cleaner syntax will work based on your server-side language. For more information on making AngularJS AJAX calls, read this great article: Make AngularJS $http Service Behave Like jQuery AJAX

Cleaner Syntax

This example sends data as a string and sets your headers. If you don’t need to do that kind of stuff and just want the cleanest Angular $http POST possible, we’ll use the shorthand method:


...
	$http.post('process.php', $scope.formData)
		.success(function(data) {
			...
		});
...

Definitely cleaner and a much easier to remember method than the above.

$http inside controllers: Ideally, you would move the $http request outside of the controller and into a service. This is just for demonstration purposes and we’ll do a write-up on services soon.

Showing the Errors and Messages in the View

We will use the directive ng-show and ng-class to handle our view. The Angular double brackets will place our variables where we need them also.

ng-show: Show or hide an element based on if a variable exists. Docs
ng-class: Add or remove a class based on if a variable exists (or some other expression). Docs

<!-- index.html -->

...

	<!-- SHOW ERROR/SUCCESS MESSAGES -->
	<div id="messages" ng-show="message">{{ message }}</div>

	<!-- FORM -->
	<form>
		<!-- NAME -->
		<div id="name-group" class="form-group" ng-class="{ 'has-error' : errorName }">
			<label>Name</label>
			<input type="text" name="name" class="form-control" placeholder="Bruce Wayne">
			<span class="help-block" ng-show="errorName">{{ errorName }}</span>
		</div>

		<!-- SUPERHERO NAME -->
		<div id="superhero-group" class="form-group" ng-class="{ 'has-error' : errorSuperhero }">
			<label>Superhero Alias</label>
			<input type="text" name="superheroAlias" class="form-control" placeholder="Caped Crusader">
			<span class="help-block" ng-show="errorSuperhero">{{ errorSuperhero }}</span>
		</div>

...

Our form is done! By using the power of Angular, we can move all of that stupid show/hide logic out of our javascript and into the view. Now our javascript file is free to just handle data and our view can do its thing.

Our classes and errors/success messages will hide and show if they are available. This is so much easier since we don’t have to worry about if we covered everything like in our old javascript. You don’t have to wonder if you remembered to hide those error messages on every form submit.

Angular Form Validation For more information on form validation, read up on our other article: AngularJS Form Validation.

Conclusion

Now we have our beautiful form fully converted to Angular. We’ve gone through a lot of concepts and hopefully as you play with them more, they will be easier to use.

We’ve gone through:

  • Creating an Angular module
  • Creating an Angular controller
  • 2-way data-binding
  • ng-model to bind inputs
  • ng-click to submit a form
  • Showing form errors using 2-way data-binding
  • Showing a div based on if a variable exists
  • Adding a class based on if a varible exists

These Angular techniques will carry over into much larger applications and there are so many great things that you can build. Have fun with Angular and stay tuned for more advanced articles. In the meantime, you can continue your Angular learning by diving into directives, services and factories, and so much more.

This article is part of the AngularJS Forms series.

Chris Sevilleja

Design, development, and anything in between that I find interesting.

View My Articles

Stay Connected With Us
hover these for magic

Get valuable tips, articles, and resources straight to your inbox. Every Tuesday.

  • Pingback: Article: Submitting AJAX Forms: The AngularJS Way ♥ Scotch | FEE

  • Sean Canton

    And if you really wanna add another level of polish and organization, make a service out of processForm

    • http://www.benyitzhaki.co.il Ben Yitzhaki

      why is that necessary? as i see it, services are good for sharing data/common methods in the app. with that on mind, in my applications i have created a service that wraps $http and has some additional methods and suits for me (better caching, uses same api url and so on..).

      am i missing anything or just having a different development approach?

      • Sean Canton

        It’s not necessary, it’s just a pattern I use constantly in Angular. It’s handy to keep all the API calls in one place. Plus it’s super easy to add promises.

      • Ut0

        Services are not only for sharing data, i.e. $http is a service. But in that case, i’m not sure to understand @seancanton:disqus’s point. $http already deals with promises. Services are useful for tests. We split components, and tests become 1) easier 2) well written. But again, in that case, I don’t think it’s necessary.

        BTW, the article is interesting, but be careful, this **is not** the angular way. Angular has already a form directive and a form controller ( http://docs.angularjs.org/api/ng.directive:form.FormController )

        • http://scotch.io/ Chris Sevilleja

          Good info on the ngForm. I didn’t know that existed. Was just sharing my experience of how great I saw using Angular for forms was. I’ll experiment with this and update the article to let more people know it exists. Thanks.

        • Ed

          I came here wanting to learn how to use that ngForm for a form. I’m still struggling, there’s no example.

          • http://scotch.io/ Chris Sevilleja

            I’m writing up an ngForm article this week. Stay tuned for that.

  • http://www.givenm.co.za/ Given M

    Good article, thanks Chris.

    • http://scotch.io/ Chris Sevilleja

      Welcome! Thanks for reading.

  • Risto Novik

    You made greate jQuery and angular example, is this more meant as SPA application or with multiple pages ?

  • iambluetest

    hello , you can try ngApi (https://github.com/iamblue/ngApi) for free controller way to write angular :)

  • iambluetest

    hello , you can try ngApi https://github.com/iamblue/ngApi for free controller way to write angular :)

  • Swapnil Dalvi

    thanx buddy you help me alot

  • matjaz

    how do you handle saving password login form? browser to show save password prompt.

  • Pingback: AngularJS Highlights: Week Ending 1 December 2013 | SyntaxSpectrum

  • gmilby

    any chance you have the complete example of each (old vs new) anywhere?
    it was confusing that you were always seemingly overwriting your own code
    Tia

    • http://scotch.io/ Chris Sevilleja

      Sorry, I was really debating on the best way to write this. I wanted it to be easy for people that didn’t do the first article to just jump right in while still accommodating the people that read the first.

      Here is the complete code for the first tutorial: https://github.com/scotch-io/easy-node-authentication/tree/local

      I’ll try to make it more clear in the next articles. Thanks for the feedback.

      • gmilby

        i worked through it, but being new to ajs – it wasn’t a piece of cake. was thinking it would be insane for someone who is totally new.
        you write well – just wanted you to get maximum affect by suggesting ‘final’ ‘complete’ code at the end or something.
        thanks for replying!

        • http://scotch.io/ Chris Sevilleja

          I think I’m losing my mind. I thought your initial comment was on a different article (so my response probably made absolutely no sense). I’ll add code samples for this article. Great job getting through the code without the samples!

          • gmilby

            my life story <3
            lol

  • Mike

    Let’s try it out.

  • dilesh

    hello can i send one more parameter in the http request ?

    • http://scotch.io/ Chris Sevilleja

      Hello. Yes you can send as many parameters as you want. Just add it to the formData variable.

  • Jake Rowsell

    Thanks for the tutorial, I get an error though in the last step.. After .success(function(data)
    {
    If I console.log(data) I get an array as expected, with { “success”: true, … However if I try to console.log(data.success) I get undefined. This also causes:

    if (!data.success) {
    $scope.errorWeight = data.errors.weight;
    $scope.errorUser = data.errors.user;
    } else {
    $scope.message = data.message;
    }
    to throw an error because the values assigned to the variables will always be undefined

    • http://scotch.io/ Chris Sevilleja

      No worries. Usually when an error like that happens, it’s because you are returning a string “success” instead of a Boolean (true/false).
      Glad you figured it out!

  • Pingback: AngularJS Form Validation ♥ Scotch

  • Pingback: Submitting AJAX Forms with jQuery ♥ Scotch

  • Arnor Kari

    This may sound stupid, but why is it $http not $ajax?

    $scope.processForm = function() {
    $http({
    method : ‘POST’,
    url : ‘process.php’,
    data : $.param($scope.formData), // pass in data as strings
    headers : { ‘Content-Type’: ‘application/x-www-form-urlencoded’ } // set the headers so angular passing info as form data (not request payload)
    })

    • http://scotch.io/ Chris Sevilleja

      That’s just the service that Angular created and named themselves to communicate with remote HTTP servers. They just named it $http.

      http://docs.angularjs.org/api/ng.$http

  • http://blog.tankist.de/ Armen

    Hi Chris!

    Thanks for a great article!

    I’m trying to survive a project without using jQuery at all. So my question is: Is there a good reason to use data: $.param in configuration for $http? Can’t one just use params: $scope.formData? That way you don’t have to use $.param from jQuery and save some string operations while gluing JSON into urlencoded string. Or do I miss something?

    • http://scotch.io/ Chris Sevilleja

      I always wondered about this as well and couldn’t get it to work without $.param. You can try it without it and see if that works for you.

      I understand the no jQuery thing and don’t know if you can do it without $.param. Angular actually comes with it’s own version of jQuery (jQLite although I’m not sure if .param is in there). I used this as reference but if you find a way to do it without .param, that’d be cool and you should post your findings here so I could learn about it too!

      http://stackoverflow.com/questions/11442632/how-can-i-make-angular-js-post-data-as-form-data-instead-of-a-request-payload

  • Jason Lunsford

    Hi Chris,

    Thanks for the well written article. I am trying to build a simple settings page for an email application and your explanations explained things in a different way from the material I’m currently reading. Very useful.

    A couple questions: do you ever take advantage of Angular’s input-level validations? Examples: ng-minlength, ng-maxlength? Or even HTML5 attributes like required (assuming modern browsers of course? Why / not?

  • jp

    Chris – good article, I got the jQuery example working perfectly, but the Angular example doesn’t seem to send anything…. I’m sure I missed something – but I’ve gone over the examples numerous times…
    The error Im getting back form the server is that – ‘name’ doesn’t exist … and the “post” data is totally empty from my angular example (did you have a complete example available?)

    Here is the header request for the jQuery example:
    Response Headers
    Connection Keep-Alive
    Content-Type text/html;charset=UTF-8
    Date Thu, 30 Jan 2014 21:02:29 GMT
    Keep-Alive timeout=5, max=97
    Server Apache/2.2.22 (Win32) mod_jk/1.2.32
    Transfer-Encoding chunked
    Request Headers
    Accept application/json, text/javascript, */*; q=0.01
    Accept-Encoding gzip, deflate
    Accept-Language en-US,en;q=0.5
    Content-Length 23
    Content-Type application/x-www-form-urlencoded; charset=UTF-8
    Cookie
    Host 127.0.0.1
    Referer http://127.0.0.1/form_submit/index_jquery.htm
    User-Agent Mozilla/5.0 (Windows NT 6.3; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
    X-Requested-With XMLHttpRequest

    Here is the header request for the AngularJS example:
    Response Headers
    Connection close
    Content-Type text/html;charset=UTF-8
    Date Thu, 30 Jan 2014 21:03:11 GMT
    Server Apache/2.2.22 (Win32) mod_jk/1.2.32
    Transfer-Encoding chunked
    server-error true
    Request Headers
    Accept application/json, text/plain, */*
    Accept-Encoding gzip, deflate
    Accept-Language en-US,en;q=0.5
    Content-Type application/x-www-form-urlencoded
    Cookie
    Host 127.0.0.1
    Referer http://127.0.0.1/index_angularJS.htm
    User-Agent Mozilla/5.0 (Windows NT 6.3; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0

    • http://scotch.io/ Chris Sevilleja

      Hey jp. Maybe try doing the POST with the shorthand way?

      $http.post(‘process.php’, $scope.formData)

      This removes the data as a string, and headers, and has cleaner syntax. Usually when you don’t get POST values on the server side, you’re sending the data from the form wrong. I’ve run into this problem a few times myself so doing a couple different combinations of sending the data through sometimes can help.

      Also, try console.logging the $scope.formData to show that you actually have an object full of information. Let me know if changing up that syntax helps.

      • jp

        Tried that – no luck.
        Also tried $.param({data : $scope.formData}); – no luck

        I posted full code here – http://stackoverflow.com/questions/21468191/angularjs-http-not-posting-as-a-form – maybe I read your stuff wrong – but the jQuery stuff worked pretty easily. and I literally just created a new page for the angular (wanting to have BOTH examples)

        Thx again – if anyone sees my ‘error’ – I’d appreciate the input.

        • Johnny Bleu

          Hey,

          check your process.php, I was having no sucess with this excelent tutorial, but digging in my code, i found that i had copied the process.php including this line : // process.php before <?php so, it sends this line to ajax's response too.

      • jp

        Tried that –

        $http.post(‘process.php’, $scope.formData)

        Also tried
        $.param({data : $scope.formData});

        No luck on either – still NOT getting a POST.

        Full code at:

        http://stackoverflow.com/questions/21468191/angularjs-http-not-posting-as-a-form

        I’m pretty sure I copied your code correctly – any help from anyone is appreciated.

        • http://scotch.io/ Chris Sevilleja

          I’ve tested the code myself and put together a Github repo. Both the Angular and jQuery versions work for me. It might have something to do with how your server is set up? https://github.com/scotch-io/submitting-forms-angular

          Also, on the jsFiddle link you posted on StackOverflow. To at least get the Angular binding working, you need:

          <div class=”container” ng-app=”formApp” ng-controller=”formController”>

          and then in the jsFiddle settings on the left for Frameworks & Extensions, change the option from onLoad to No wrap – in <head>

          • jp

            Thx Chris – alas, I guess I’m just missing something – even in jsfiddle, with the changes – firebug still shows NO post information…. I’ll agree that my server is set up differently, but I’ll suggest that you’ve implemented something to handle a “not-post” type of post… Im running a pretty stock apache/coldfusion set up. but disregard the server side – because the browser is telling me that the browser isn’t passing anyting in the POST scope…

            I’ve included 2 images – one of angular code running, the other of your jquery example – note the firebug console differences… this makes me suspect that IF it’s working for you, you’ve done something serverside to process BEYOND the “post” vars – PHPs $_POST['name'] is the same as ColdFusions form.name – so I have a hard time realy pinning it on theserver when the browser behavior is telling be the code ISNT passing something the docs and you blog say it should be – specifically headers : { ‘Content-Type’: ‘application/x-www-form-urlencoded’ } SHOULD be forcing the method to POST data.

            Thx for your help regardless – appreciate the post – and especially appreciate any extra time you put in to help resolve my issues… I’ll try it all at home where I have PHP set up – and see if it makes a diff.

          • http://scotch.io/ Chris Sevilleja

            Good luck with changing the environment and let me know if that works. Wish I could help more and I’ve been looking around at other ways to send POST data but I’m afraid these are the main ways I’ve seen.

            I’m sure you’ve already seen this but maybe: http://stackoverflow.com/questions/19254029/angularjs-http-post-does-not-send-data

  • Bo Boland

    I’m new to Angular (and JS in general. I just finished a few online courses) and this was pretty helpful. One thing I wanted to ask about… if you submit and get an error, the error span appears. If you then correct your values, it will say “Success”, but the error spans remain. Is there an option in Angular to make those go away? Or should we write some custom jQuery to check for that?

    • http://scotch.io/ Chris Sevilleja

      Yes there are ways to handle validation in completely Angular. You usually don’t want to do any custom jQuery inside your Angular controllers. This makes testing your controllers in the future very hard.

      Angular comes with its own validation classes and can help you show and hide error messages. Check out our other tutorial for more info: http://scotch.io/tutorials/javascript/angularjs-form-validation

  • Craig

    Why does the angular version require loading jQuery? This doesn’t work without it.

    • Craig

      Nevermind using the cleaner syntax allows you to remove jQuery. Thanks.

      • http://scotch.io/ Chris Sevilleja

        The jQuery is used for the $.param function to serialize the data so that PHP can read the data. This is because Angular serializes and sends data differently and PHP doesn’t read it well. There are many ways around this but if you’re server language can recognize the Angular serialized data, then the cleaner syntax works.

  • Pingback: Ajax with Angular in Angular way | My Dev Note

  • http://blog.minharendaextra.com/ Danilo Jr.

    Hello,

    I know, this tutorial is for PHP, but how can I send a success message when I save a entity with AngularJS (using $resource) + NodeJS (Express. Ex.: res.json(savedUser))?

    And thanks for your sharing! This content is amazing! My favorite!

    • http://scotch.io/ Chris Sevilleja

      You could pass that back in the object that you pass back in Node.

      res.json({
      user: savedUser,
      message: ‘this is my success message’
      });

      Then you can use that in Angular when you get the data back from your $resource call. data.message

  • RL435

    This works very well. I stumble when I add multiple checkboxes. I can’t seem to get them to post.
    Any ideas or examples?

  • Pingback: Handling Checkboxes and Radio Buttons in Angular Forms ♥ Scotch

  • Sam

    Hello, I’m trying to send the input-values to a database. For testing I put the connection and insertion in the if-statement that checks if there are no error-messages (process.php). The values get inserted, but I keep getting the error: ‘TypeError: Cannot read property ‘name’ of undefined’ and there is no success message. How is this possible?

    • http://scotch.io/ Chris Sevilleja

      Hello, can you add

      .error(function(data) {

      console.log(data);

      });

      after your .success? This will console log any errors that come from the server.

      Also, Angular sends POST data a little differently than jQuery AJAX. You will need to make sure that Angular is sending the data correctly. Make sure you include all of the following in your POST.

      method : ‘POST’,
      url : ‘process.php’,
      data : $.param($scope.formData), // pass in data as strings
      headers : { ‘Content-Type’: ‘application/x-www-form-urlencoded’ }

  • Arvind Ravulavaru

    Thanks Chris! The post was helpful.

  • Rashed

    Chris, fantastic tutorial. Can you help me with textarea input in the same example?

    • http://scotch.io/ Chris Sevilleja

      You should be able to add ng-model to the textarea and have it work the same as the input fields.

      • Rashed

        Works fine. But trying to add CKEditor in the textarea, then it doesnt work. Can’t figure it out.

        • http://scotch.io/ Chris Sevilleja

          I see. When affecting an element after the page is being created (with CKEditor in this case), Angular won’t have that information bound because it is being affected after Angular does its thing.

          You will need to create a directive so that Angular knows how to handle the data in that CKEditor. Here is a StackOverflow question where someone had the same problem. Hope that helps.

          http://stackoverflow.com/questions/18917262/updating-textarea-value-with-ckeditor-content-in-angular-js

  • http://www.jankoprester.com Janko Prester

    Thnx man! Amazing stuff. I was wondering, could you guys make a tutorial for AngularJS+PHP built simple CRUD app? It is extremely annoying that it is impossible to find a good tutorial for this on the web .

  • Pingback: Google

  • nununu

    Angular looks cool and all, but all those extra attributes in HTML almost reminds me of the old days of “obtrusive” JS when we used to use onSubmit attributes and such. I guess it’s good if you work with Ajax only forms.

  • soyuka

    Why are you loading jquery with angularjs ? It’s not needed in this example and would be a best-practice for newbies to not use jquery while beggining to work with angularjs (http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background/15012542#15012542)

    • http://scotch.io/ Chris Sevilleja

      Above in the alert box it states why. I know this isn’t the ideal scenario but it was used just to send the data to the PHP server and make it so that PHP could process it.

      The above code is for a PHP server and jQuery is needed for the $.param function. There are ways to do it without jQuery but that’s pretty much the only reason jQuery was included for this example. Because it was easier.

  • Bigo

    Hello ! thank you, great article !
    I’am trying to build a contact form from this base. To you, what is the clean way to put the data in a mail and send it ?

  • http://scotch.io/ Chris Sevilleja

    I completely agree with you that jQuery should be removed completely. Just tested the params thing but PHP just doesn’t recognize the data coming through. http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

    I’ve added more warnings in the tutorial about this until I can come up with a better solution. Maybe I’ll adjust the tutorial to have Node process the form.

    • soyuka

      Really interesting link! I’ll be working on an auth system with PHP and angular, I’ll get in touch if I found a nice workaround ;).
      Thanks for the work anyway you’re writing nice tuts! <3

  • modern_legend

    Hey Chris, it doesn’t look like your code actually sets up the css for the ‘success’ message, nor is there any code here that clears the error messages upon submitting a successful set of values after having failed the first time. Just wanted to confirm that this is expected behavior given the current code you provide here. Great tutorial, still.

    • http://scotch.io/ Chris Sevilleja

      No, must’ve just skimmed over that. I’d probably add Bootstrap classes like alert and alert-success to it.

      Also, to clear it, just add $scope.messages = {}; inside of the processForm function. Both good points. Thanks.

  • Pingback: AngularJS-Learning | Nisar Khan

  • Pingback: AngularJS隨筆記 | Web Development Notes

  • Pingback: AngularJS Contact Form with Bootstrap and PHPMailer | Matt Smith Blog

  • Md.Ibrahim

    Really appreciate this article. But I cannot submit the form data with the shorter syntax to my WebAPI action without including ‘Content-Type’: ‘application/x-www-form-urlencoded’. Any ideas to why? With jQuery $.post() works fine.

  • jzgdev

    Thanks for the tutorial, very helpful.. I’m able to call processForm() to POST data as JSON and to POST as x-www-form-urlencoded (as per this tutorial); while having the correct data is a good start; I get 404 errors on each method. I’m fairly certain it’s a server-side issue, and though I’ve tried numerous methods, am still unable to get things to work correctly. Any chance you could give some more details as to your server-side code/configuration? So far I’ve been trying to proxy Express through Nginx for POST requests of this nature but not sure if that is the best way to do things. Any insight is greatly appreciated.

  • Luigi Del Mare

    Hi there. Thank you for your article :) It helped me a lot. I’m trying to add email validation to your example and but it seems nothing works :-/ Since i’m new to Anglular I read several articles and I tried even more examples but I cannot get it right. Could anyone help? Thanks in advance!

  • bijbiz

    1. I applied your method to my form and I found a problem with datepickers! I have a datepicker which uses jquery to show a tiny calendar as the user clicks on the input and he has to select a date from that tiny calendar and it would populate the input automatically (like any other datepicker!) So the user doesn’t actually type anything in that input manually and the formData doesn’t catch it! unless I manually type a ‘space’ after the date!
    2. I saw you have a similar approach for checkboxes and radio buttons, I tried to apply that to comboboxes ( element) but it didn’t work when I added ng-model to my element! can you help with that?

    • http://scotch.io/ Chris Sevilleja

      Hello. The problem is that Angular isn’t bound to that datepicker. What you want to use is a directive which helps Angular watch that element for changes. Luckily there is Bootstrap UI that comes with built in things like this.

      http://angular-ui.github.io/bootstrap/