Rails

Server Side Validation With Angular Js & Rails

Posted by Weston Ganger on August 05, 2014

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>
  </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>
  </span>

  <input type="submit" />

</form>

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(result.data.errors, 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 PostService.save(post).$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 = Phrase.new(phrase_params)
        @phrase.save
        respond_with @phrase, location: "" #this is the part where is returns the success or returns errors with the response
      end
      
      def create
        @phrase = Phrase.find(params[:id])
        @phrase.update(phrase_params)
        respond_with @phrase, location: "" #this is the part where is returns the success or returns errors with the response
      end
      
      #more code.....   
    end
  end
end

Basically this is what respond_with does automatically


if @phrase.save
  render json: @phrase, status: 200
else
  render json: {errors: @phrase.errors}, status: 422
end

You now have server side validation! Congrats!


Posted in Rails and Tagged with angular angularjs rails javascript framework js json 


Want me to help develop your next project or application?

Contact Us

Specializing in Ruby-on-Rails, Javascript, Multi-Platform Electron Desktop Apps and Hybrid Cordova Mobile Apps.

Recommended Posts