Server Side Validation With Angular Js & Rails

Posted By Weston Ganger

This is a step by step guide for Server Side form validations with AngularJS and Rails backend

Most of the information comes from the following article but I add some important information that was left out:

Server Form Validation with Angular.js

We will start with the form:

<form name="yourForm" ng-submit="addPost()" novalidate>
  <input type="text" name="title" ng-model="newPost.title" server-error />
  <!--take note the name attribute must be the exact same as the attribute name in your rails model -->
  <span class="errors" ng-show="yourForm.title.$dirty && yourForm.title.$invalid">
    <span ng-show="yourForm.title.$error.server">{{errors.title}}</span>

  <input type="text" name="content" ng-model="newPost.content" server-error />
  <span class="errors" ng-show="yourForm.content.$dirty && yourForm.content.$invalid">
    <span ng-show="yourForm.content.$error.server">{{errors.content}}</span>

  <input type="submit" />


The "novalidate" turns off the in-browser HTML5 validations which we dont want for Angular and the "server-error" makes a call to our directive that we will be making next.

Next we will create the directive that waits for input change then invalidates the server error until submission again:

angular.module('yourApp').directive('serverError', function(){
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope,element,attrs,ctrl){
      return element.on('change keyup', function(){
        return scope.$apply(function(){
          return ctrl.$setValidity('server', true);

Now we will add the functionality to your controller:

angular.module('yourApp').controller('PostCtrl', function($scope, PostService) {
  $scope.addPost = function() {
var error, success, newPost; newPost = $scope.newPost; $scope.errors = {}; //clean up previous server errors success = function(result) { //things to do if it returns success, here is my example code, will likely be different for you $scope.posts.unshift(result); $scope.newPost = {}; }; error = function(result) { angular.forEach(, function(errors, field) { $scope.yourForm[field].$setValidity('server', false); $scope.errors[field] = errors.join(', '); }); }; // if you are using $http in your server do this // return PostService.create(post).then(success, error); // otherwise if you are using $resource in your service do this // return$promise.then(success, error); }; });

Lastly we will change your models Rails Controller so that it returns the errors as json:

module Api
  module V1
    class PhrasesController < ApplicationController
      respond_to :json

      #other code.....

      def create
        @phrase =
        respond_with @phrase, location: "" #this is the part where is returns the success or returns errors with the response
      def create
        @phrase = Phrase.find(params[:id])
        respond_with @phrase, location: "" #this is the part where is returns the success or returns errors with the response
      #more code.....   

Basically this is what respond_with does automatically

  render json: @phrase, status: 200
  render json: {errors: @phrase.errors}, status: 422

You now have server side validation! Congrats!

Article Topic:Software Development - Rails

Date:August 05, 2014