Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DRY AngularJS Controllers for forms

I'm using AngularJS on a web project and I am noticing that almost all of my form controllers are looking the same. The only difference with the login controller (shown below) and say my reset password controller is $scope.loginForm.$invalid would be $scope.resetForm.$invalid and I would inject and use the ResetService instead of the AuthService.

angular.module('app').controller('LoginCtrl', function ($scope, AuthService) {

  // Form input data
  $scope.formData = {};

  // Are we in the middle of a submit process?
  $scope.busy = false;

  // Has the form been submitted yet?
  $scope.submitted = false;

  // Attempt to submit form via AJAX
  $scope.submit = function (actionUrl) {

    $scope.busy = true;
    $scope.submitted = true;

    // Invalid, activate form and return
    if ($scope.loginForm.$invalid) {
      $scope.busy = false;
      return;
    }

    // Submit data via AJAX
    AuthService.login(actionUrl, $scope.formData).error(function () {
      $scope.busy = false;
    });

  };

});

Obviously, this doesn't feel very DRY, and I am assuming that there is an Angular feature or pattern to extract this similar functionality out?

like image 704
Mike McLin Avatar asked Jun 22 '26 21:06

Mike McLin


1 Answers

A FormCtrl controller was created with all of the functionality. The 2 items that could vary from form to form are the form name attribute and the AJAX method on the service being used for the form, so I pass those two params in the function after the $scope. I then refactored the code a tad to make use of those variables I passed into the function.

The only thing that needs to happen in the LoginCtrl (or any other form controller that implements this) is to instantiate the FormCtrl and pass it the $scope, form name attribute and finally the service method that is used to make the AJAX request.

login.html

<form ng-controller="LoginCtrl"
      ng-submit="submit('my-ajax-url.php')"
      name="loginForm">
  ...
</form>

FormCtrl.js

angular.module('app').controller('FormCtrl', function ($scope, formName, ajaxFunction) {

  // Form input data
  $scope.formData = {};

  // Are we in the middle of a submit process?
  $scope.busy = false;

  // Has the form been submitted yet?
  $scope.submitted = false;

  // Attempt to submit form via AJAX
  $scope.submit = function (actionUrl) {

    $scope.busy = true;
    $scope.submitted = true;

    // Invalid, activate form and return
    if ($scope[formName].$invalid) {
      $scope.busy = false;
      return;
    }

    // Submit data via AJAX
    ajaxFunction(actionUrl, $scope.formData).error(function () {
      $scope.busy = false;
    });

  };

});

LoginCtrl.js

angular.module('app').controller('LoginCtrl', function ($scope, $controller, AuthService) {

  // Instantiate form controller
  $controller('FormCtrl', {
    $scope: $scope,
    formName: 'loginForm',
    ajaxFunction: AuthService.login
  });

});
like image 157
Mike McLin Avatar answered Jun 24 '26 10:06

Mike McLin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!