1

Feel free to clear up any misunderstandings you see here; I'm not a front end guy.

Now, I've read that much of the logic shouldn't exist in the controller, and that it should be put somewhere else. But most places I look that show code don't specify which file it belongs in. On this project that I've inherited I have 4 files that deal with the main functionality:

  • A controller - autoDeploy.js
  • A service - autoDeploy.service.js
  • A module - autoDeploy.module.js
  • Directives - directives.js

directives.js just contains the templates that I want to inject into the DOM upon the click of a button, the directives will be referenced later.

autoDeploy.module.js does all of the module.config and $stateProvider routing stuff; I don't touch it beyond my initial modification to point to the new page I'm making so it can be properly routed to.

autoDeploy.service.js: In the examples I've seen, the .factory()'s (or .service()) last parameter usually opens up as a function, and all of the functionality in the file happens inside there. Mine isn't like that, it's an iife with the factory being a standalone command followed by what looks like a constructor. Here's what I have:

(function () { //start iife

    'use strict';


    angular.module('gms.autoDeploy')
        .factory('AutoDeployService', ["$http", "$q", "$log", "$cookies", "APP_CONFIGS", "SweetAlert", "$timeout", "GridSettingsService", "APP_USER", AutoDeployService]);

    function AutoDeployService($http, $q, $log, $cookies, APP_CONFIGS, $timeout, SweetAlert, GridSettingsService, APP_USER) {
        //return service object at bottom of function

        function returnOne() {
            return "one";
        }

        var service = {
            returnOne: returnOne
        };

        return service;

    } //end AutoDeployService
}()); //end iife

Why did the original developer...

  • Use as an iife?
  • Return the service variable after making it a function mapping?
  • Put all of the functionality in the constructor like function?

My guess to the above 2nd and 3rd answers is that it is the constructor for the service and the controller can some how know it's a usable object because we pass it in as a parameter to the controller as you can see on the top line of the code below. I also don't know much about the parameters for the "constructor", but I can look those up later.

Now for the controller. Unlike the service above, the controller declaration does open up as a function in the parameters of .controller() as I've seen other places. Here it is, simplified (methods with similar functionality are cut out):

angular.module("gms.autoDeploy").controller('AutoDeployController', ['$scope', '$compile', 'AutoDeployService',
    function ($scope, $compile, AutoDeployService) {
        var vm = this;

        init();

        function init() {
            vm.isInstantiated = true;
            vm.data = {
                "parameter": []
            };

        }

        // calling a function from the service to show that we can pass
        // data from controller to service
        vm.change = function () {
            vm.message = AutoDeployService.returnOne("not one");
        };

        //function assigned to button click on the DOM allowing
        // the directive to inject the template where the <tib-copy> tag is
        vm.addCopy = function (ev, attrs) {
            var copy = angular.element(document.createElement('copy'));
            var el = $compile(copy)(vm);
            angular.element(document.getElementsByTagName("tib-copy")).append(copy);
            vm.insertHere = el;
        };

        // This method extracts data from the following fields dynamically added by the click of a button:
        //  - TIBCO Server(s)
        //  - TIBCO Domain(s)
        //  - TIBCO Application(s)
        vm.getTibPromotionData = function () {
            // Add all TIBCO servers
            var servers = document.getElementsByName("tibServer");
            var tibSvrList = [];
            for (var i = 0; i < servers.length; i++) {
                tibSvrList.push(servers[i].value);
            }

            // Add all TIBCO domains
            var domains = document.getElementsByName("tibDomain");
            var tibDomainList = [];
            for (i = 0; i < domains.length; i++) {
                tibDomainList.push(domains[i].value);
            }

            // Add all applications
            var tibApps = document.getElementsByName("tibApp");
            var tibAppList = [];
            for (i = 0; i < tibApps.length; i++) {
                tibAppList.push(tibApps[i].value);
            }


            // Add the processed data to the final JSON
            vm.data.parameter.push({
                "name": "TIBCO_Promotion",
                "value": JSON.stringify("[{\"server\":[" + tibSvrList + "]},{\"domain\":[" + tibDomainList + "]},{\"application\":[" + tibAppList + "]}]")
            });
        };
    }
]);

Please, let me know if you see anything in the controller that should belong in the autoDeploy.service.js file. Furthermore, if anyone has experience with this file naming convention, I'd love to hear an explanation as to why there are files named *.service.js and *.module.js, and if the *.service.js file has anything to do with the concept of services and factories, or if it's intended to be conceptual, as if it's just a reference to being the back end services component.

Darrel Holt
  • 870
  • 1
  • 15
  • 39
  • 1
    Methodology in controller is completely backwards to typical angular methodology whereby the data model is used to drive the view and not dom manipulation methods. That is a bad example to learn from. The file names are conceptual and are arbitrary – charlietfl Nov 09 '17 at 01:37
  • 1
    See : [“Thinking in AngularJS” if I have a jQuery background](https://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background) – charlietfl Nov 09 '17 at 01:41
  • Thanks @charlietfl. I enjoyed the read and learned a few things. Ultimately though, I still don't know where the methods in the controller should go. As you can see, they use the `this` and `$compile` variables to create and insert elements. How would I do this otherwise? I need to dynamically add the templates on the click of a button and I don't see how that can be done anywhere other than in the controller. What should I add to the service to make it work, or should I make another file for the functionality to reside in? – Darrel Holt Nov 09 '17 at 18:05
  • 1
    Normally you would use something like `ng-repeat` and add data to model array instead of using dom methods. That's why your controller is using a completely wrong approach – charlietfl Nov 09 '17 at 18:48
  • @charlietfl A colleague mentioned using `ng-repeat`, but wouldn't there be a conflict relating to the two-way data binding due to duplicate instances of `ng-model` in the view? I think you guys had the same idea. Would you mind providing a small example? – Darrel Holt Nov 09 '17 at 18:58
  • Finding examples is not difficult. It is one of the most commonly used parts of angular – charlietfl Nov 09 '17 at 19:03
  • @charlietfl I've seen examples showing `ng-repeat` such as [this](https://www.airpair.com/angularjs#5-controllers), but they're very basic and don't mention a "data to model array". Let alone dynamically adding duplicate fields that can be referenced uniquely with `ng-model`. You say finding examples for such a specific issue isn't difficult, then it should only take you a few seconds to mention one versus the days I've spent trying to find what I need without knowing what concept I'm looking for, and it's further impacted by such basic examples when I've been dropped into a complex project. – Darrel Holt Nov 09 '17 at 19:14
  • 1
    Really basic example http://plnkr.co/edit/dIfpDdgIDH3rMq908PS0?p=preview – charlietfl Nov 09 '17 at 19:30
  • Thank you @charlietfl, I learned a lot more of what I need with that example than most of the shallow blanket tutorials I've seen. – Darrel Holt Nov 09 '17 at 19:36
  • @charlietfl Your example was the perfect solution for several of my problems. If you'd like, post it as an answer and I'd be happy to accept it. – Darrel Holt Nov 10 '17 at 18:40

0 Answers0