Search code examples
javascriptangularjsangularjs-serviceangularjs-controllerangularjs-factory

AngularJS : Guidance to implement a factory, service, directive or something else


I'm very new to angularjs and need some advice about the angular way to implement something very simple. In my $scope I need to set some field defaults, and these defaults are needed multiple times in my controller.

I want to be able to refactor these defaults out to a common place, to thin out the controller and allow for code reuse, but not sure if this should be a factory, directive or service.

Heres an example of the defaults:

$scope.skills = [{
  description: '',
  years: "1",
  level: "0",
  years_values: [
    { id: "1", description: "1" },
    { id: "2", description: "2" },
    { id: "3", description: "3+" }],
  level_values: [
    { id: "0", description: "Starter"},
    { id: "1", description: "Intermediate"},
    { id: "2", description: "Advanced"} ]
}]

Here's an example of where I'd like to call the "new function":

skillSuccess = (resp)->
  Loader.hide();
  $rootScope.current_user = resp;
  #TODO replace this repetition
  $scope.skills = [{
    description: '',
    .... etc

My questions are:

  1. Should I use a factory/directive/service, (or something else) for this refactoring?
  2. How do I ensure that the function gets called initially so that the default values are available for the fields when the page loads?

Solution

  • Should I use a factory/directive/service, (or something else) for this refactoring?

    A controller should be used to set the scope, but the default values should be stored as a constant and returned by a factory. A factory pattern is preferred here because it is a singleton.

    angular.module('myApp')
        .factory('skillsFactory', function (defaultSkills) {
            var service = {};
    
            service.getDefaults = function () {
                return defaultSkills;
            };
    
            return service;
        })
        .constant('defaultSkills', [{
            description: '',
            years: "1",
            level: "0",
            years_values: [{
                id: "1",
                description: "1"
            }, {
                id: "2",
                description: "2"
            }, {
                id: "3",
                description: "3+"
            }],
            level_values: [{
                id: "0",
                description: "Starter"
             }, {
                id: "1",
                description: "Intermediate"
            }, {
                id: "2",
                description: "Advanced"
            }]
        }]);
    

    How do I ensure that the function gets called initially so that the default values are available for the fields when the page loads?

    In your controller, call $scope.skills = skillsFactory.getDefaults();

    angular.module('myApp')
        .controller('skillsCtrl', function ($scope, skillsFactory) {
            $scope.skills = skillsFactory.getDefaults();
        });