1

So upon building this application I have noticed that some of my controllers are almost identical. I like to keep things DRY so I was hoping to figure out a way to make a generic controller that other controllers can inherit from, but I got a little confused by some of the things I found. Here is an example of 2 of my controllers so you can see the similarities:

.controller('CompaniesController', ['$state', '$filter', 'ArrayService', 'CompanyService', 'toastr', 'companies', 'roles', function ($state, $filter, arrayService, service, toastr, companies, roles) {

    // Assign this to a variable
    var self = this;

    // Get our companies
    self.companies = companies;

    // Our selected companies
    self.selected = [];
    self.send = {};
    self.delete = {};

    // Create our page sizes array
    self.pageSizes = [10, 20, 50, 100];

    // For filtering and sorting the table
    self.pageSize = self.pageSizes[0];
    self.predicate = 'email';
    self.reverse = false
    self.filter = '';

    // Select method
    self.select = function (company) {

        // Modify our array
        arrayService.modify(self.selected, company);

        // If our array is only 1
        if (self.selected.length === 1) {

            // Get the current selected company
            var current = self.selected[0];

            // Set our variables
            self.canHaveCenters = (current.role === 'Company');
            self.requiresConfirmation = (!current.emailConfirmed);

            // Else
        } else {

            // Reset our variables
            self.canHaveCenters = false;
            self.requiresConfirmation = false;
        }
    };

    // Check to see if the row is selected
    self.isSelected = function (company) {

        // If our item is in our array, return true
        return (arrayService.indexOf(self.selected, company) > -1);
    };

    // Change to the edit company state
    self.edit = function (e, company) {

        // Change our state
        changeState(e, company, 'saveCompany.edit');
    };

    // Change to the company centers state
    self.centers = function (e, company) {

        // Change our state
        changeState(e, company, 'saveCompany.centers');
    };

    // Deletes a company
    self.delete = function (e, company) {

        // Perform the delete
        recursion(e, company, service.delete, self.delete, '{0} has been deleted.', '{0} companies have been deleted.', true);
    };

    // Private recursion method
    var recursion = function (e, company, serviceCall, resultObject, singleMessage, multipleMessage, removeAfterExecution) {

        // Stop propagation
        e.stopPropagation();

        // If we have an index
        if (typeof company !== 'undefined') {

            // If our delete succeeded
            serviceCall(company.id).then(function () {

                // If we are to remove
                if (removeAfterExecution) {

                    // Remove the company from our array
                    self.companies.data.splice(index);
                }

                // Display a message
                toastr.success($filter('stringFormat')(singleMessage, company.email));
            });

            // Otherwise we have no index
        } else {

            // Create our counter
            var i = 0;

            // Create a variable to hold our errors
            var errors = [];

            // For each selected company
            for (i; i < self.selected.length; i++) {

                // Get our index
                var index = self.selected[i];

                // Get the current company
                var company = self.companies.data[index];

                // If we have a result
                serviceCall(company.id).then(function () {

                    // If we are to remove
                    if (removeAfterExecution) {

                        // Remove the company from our array
                        self.companies.data.splice(index);
                    }

                    // If there is an error
                }, function (error) {

                    // Add to our errors array
                    errors.push(error);
                });
            }

            // If we have some errors
            if (errors.length > 0) {

                // Set our delete error
                self.error = errors.join();

                // Otherwise everything worked
            } else {

                // Display a message
                toastr.success($filter('stringFormat')(multipleMessage, i));
            }
        }
    };

    // Private state change method
    var changeState = function (e, company, state) {

        // Stop propagation
        e.stopPropagation();

        // If we have an index
        if (typeof company !== 'undefined') {

            // Change state
            $state.go(state, { companyId: company.id });

            // Otherwise we have no index
        } else {

            // If we have 1 selected item
            if (self.selected.length === 1) {

                // Get our index
                index = self.selected[0];

                // Get our company
                var company = self.companies.data[index];

                // Change state
                $state.go(state, { companyId: company.id });
            }
        }
    }
}]);

and

.controller('UserCentersController', ['$stateParams', 'ArrayService', 'CenterService', 'centers', 'userCenters', function ($stateParams, arrayService, service, centers, userCenters) {

    var self = this;

    // Get our user Id
    var userId = $stateParams.userId;

    // Assign our centers
    self.centers = centers;
    self.userCenters = userCenters;

    // Create our page sizes array
    self.pageSizes = [10, 20, 50, 100];

    // For filtering and sorting the table
    self.pageSize = self.pageSizes[0];
    self.predicate = 'name';
    self.reverse = false;
    self.filter = '';
    self.selected = [];

    // Create a function to check if a center is in an array
    self.contains = function (center) {

        // Reference our data
        var data = self.userCenters.data;

        // If we have any data
        if (data) {

            // Check to see if our center is in the array
            return arrayService.indexOfByKey(data, 'id', center.id) > -1 ? true : false;
        }
    };

    // Adds the current center to the user
    self.add = function (e, center) {

        // Stop propagation
        modify(e, center, true);
    };

    // Removes the current center from the user
    self.remove = function (e, center) {

        // Stop propagation
        modify(e, center, false);
    };

    // Select method
    self.select = function (center) {

        // Modify our array
        arrayService.modify(self.selected, center);

        // Assign our variables
        self.canAdd = searchArray(self.userCenters.data, self.selected, false);
        self.canRemove = searchArray(self.userCenters.data, self.selected, true);
    };

    // Check to see if the row is selected
    self.isSelected = function (center) {

        // If our item is in our array, return true
        return (arrayService.indexOf(self.selected, center) > -1);
    };

    // Private method for checking if the selected items are all of the same state
    var searchArray = function (arrayToCheck, arrayToCompare, contains) {

        // Loop through the items to check
        for (var i = 0; i < arrayToCompare.length; i++) {

            // Get our current item
            var item = arrayToCompare[i];

            // See if our current id exis
            var found = arrayService.indexOfByKey(arrayToCheck, 'id', item.id) > -1;

            if (found != contains)
                return false;
        }

        return true;
    };

    // Private method for handling adding / removing or user centers
    var modify = function (e, center, adding) {

        // Stop propagation
        e.stopPropagation();

        // If we have an index
        if (typeof center !== 'undefined') {

            // Create a list
            var list = [];

            // Push our center into the list
            list.push(center);

            // Make our call
            service.modifyUserCenters(list, userId, adding).then(function () {}, function (error) {

                // Display our error
                self.error = error;
            });

            // Push to our user centers if it's not already there
            arrayService.modify(self.userCenters.data, center);
        }
    };
}]);

Now there are obvious differences, but at the same time there are a lot of similarities. As I am not a JavaSript Guru, things like prototypical inheritance don't really mean anything to me.

I saw this question someone else asked:

Creating a generic angularjs listController

and it seems similar to what I want, but then I stumbled upon these 2 methods:

https://www.exratione.com/2013/10/two-approaches-to-angularjs-controller-inheritance/

and that is where I started getting confused. For my case as you can see, I will probably have similar methods calls and will have some shared variables and functions. I have about 5 controllers that are similar in design and I can see that if I solve this, then I will have a few more for creating / editing controllers too.

Can someone give me, a laymen, a helping hand?

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.