0

I am very new to AngularJs and hope I can get some help here. Below I have two controllers that are very similar. One is for editing an item and one for adding a new item. I would like to know how I can refactor this code in order to reuse most of this code for both controllers or simply use one controller for both. I originally tried to use one controller for both but the new item page wouldn't let me type anything into the fields. I supposed because there was no current model data like there is when editing.

Any help would be appreciated.

tplApp.controller('editController', function ($scope, $http, $routeParams){

    $scope.template = {};
    $scope.id = $routeParams.template_id;

    $http.get(baseUrl+'templates/get_template/'+$scope.id).success(function(data) {
        $scope.template = data;
    });

    $scope.bodyOptions = {
        plugins: 'link image code',
        toolbar: 'bold, italic, underline,  alignleft, aligncenter, alignright, alignjustify, styleselect, bullist, numlist, outdent, indent, removeformat, mybutton, code',
        height: 300,
        menubar: false,
        statusbar: false,
        setup: function(editor) {
            editor.addButton('mybutton', {
                type: 'menubutton',
                text: 'Variables',
                icon: false,
                menu: [
                    {text: 'Candidate Name', onclick: function() {editor.insertContent('%name%');}},
                    {text: 'Company Name', onclick: function() {editor.insertContent('%company-name%');}},
                    {text: 'Today\'s Date', onclick: function() {editor.insertContent('%date%');}},
                    {text: 'Your Name', onclick: function() {editor.insertContent('%your-name%');}},
                ]
            });
        }
    };

    $scope.saveTemplate = function() {
        $http({
            method  : 'POST',
            url     : baseUrl+'templates/save',
            data    : $.param($scope.template),  
            headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  
        })
        .success(function(data) {
            $scope.message = data.message;
            if (data.success) {
                console.log(data);
                $scope.templates = data.templates;
            }
        });
    };



});



tplApp.controller('addController', function ($scope, $http){

    $scope.template = {};

    $scope.bodyOptions = {
        plugins: 'link image code',
        toolbar: 'bold, italic, underline,  alignleft, aligncenter, alignright, alignjustify, styleselect, bullist, numlist, outdent, indent, removeformat, mybutton, code',
        height: 300,
        menubar: false,
        statusbar: false,
        setup: function(editor) {
            editor.addButton('mybutton', {
                type: 'menubutton',
                text: 'Variables',
                icon: false,
                menu: [
                    {text: 'Candidate Name', onclick: function() {editor.insertContent('%name%');}},
                    {text: 'Company Name', onclick: function() {editor.insertContent('%company-name%');}},
                    {text: 'Today\'s Date', onclick: function() {editor.insertContent('%date%');}},
                    {text: 'Your Name', onclick: function() {editor.insertContent('%your-name%');}},
                ]
            });
        }
    };

    $scope.saveTemplate = function() {
        $http({
            method  : 'POST',
            url     : baseUrl+'templates/save',
            data    : $.param($scope.template),  
            headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  
        })
        .success(function(data) {
            $scope.message = data.message;
            if (data.success) {
                console.log(data);
                $scope.templates = data.templates;
            }
        });
    };



});

3 Answers3

0

What you want is a service: https://docs.angularjs.org/guide/services "You can use services to organize and share code across your app"

Google it and/or look here in SO for more info.

JonyD
  • 1,237
  • 3
  • 21
  • 34
  • Thanks but I have already checked the documentation otherwise I wouldn't post a question. The documentation isn't making sense to me. I'm not sure how to convert the sample to what I am doing, or where to put it or how to call it. As I mentioned I am very new to AngularJs. – ThEwHiStLeR Apr 29 '16 at 14:52
0

Try these changes. You will need 2 services + 2 controllers (for saveTemplateService.js and buildBodyOptionsService.js ). The services will be injected to the controllers.

At the end,don't forget to add the src of each service in the template/html file.

I think it could be even more reduced (without the $http's success in the controllers) but since we are working with callbacks here, I'm not sure. Try it out ;).

It might not be fully functional because I don't have all your code. But debugging should solve it.

saveTemplateService.js:

app.factory('saveTemplateService', function ( baseUrl, $http ) {
    return $http({
                method  : 'POST',
                url     : baseUrl+'templates/save',
                data    : $.param($scope.template),  //fix these (injecting them like baseUrl)
                headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  
            });
});

buildBodyOptionsService.js:

app.factory('buildBodyOptionsService', function() {
     return {
         build: function ( editor ) { //maybe editor needs to be injected
            var output = {
                plugins: 'link image code',
                toolbar: 'bold, italic, underline,  alignleft, aligncenter, alignright, alignjustify, styleselect, bullist, numlist, outdent, indent, removeformat, mybutton, code',
                height: 300,
                menubar: false,
                statusbar: false,
                setup: function(editor) {
                    editor.addButton('mybutton', {
                        type: 'menubutton',
                        text: 'Variables',
                        icon: false,
                        menu: [
                            {text: 'Candidate Name', onclick: function() {editor.insertContent('%name%');}},    //  I dont like this functions here. There must be a better way to do this (ex: in a partial html with ng-click)
                            {text: 'Company Name', onclick: function() {editor.insertContent('%company-name%');}},
                            {text: 'Today\'s Date', onclick: function() {editor.insertContent('%date%');}},
                            {text: 'Your Name', onclick: function() {editor.insertContent('%your-name%');}},
                        ]
                    });
                }
            };
            return output; 
         }
     };
});

editController.js

tplApp.controller('editController', function ($scope, saveTemplateService, buildBodyOptionsService) {
    $scope.template = {};

    $scope.id = $routeParams.template_id;
    $http.get(baseUrl+'templates/get_template/'+$scope.id)
            .success(function(data) {
                $scope.template = data;
    });

    // call 1st service
    $scope.bodyOptions = buildBodyOptionsService.build( editor );

    // call 2nd service
    $scope.saveTemplate = saveTemplateService.success( function(data) {
        $scope.message = data.message;
            if (data.success) {
                console.log(data); //use $log.info() instead
                $scope.templates = data.templates;
            }
    });
});

addController.js

tplApp.controller('addController', function ($scope, saveTemplateService, buildBodyOptionsService) {
    $scope.template = {};

    // call 1st service
    $scope.bodyOptions = buildBodyOptionsService.build( editor );

    // call 2nd service
    $scope.saveTemplate = saveTemplateService.success( function(data) {
       $scope.message = data.message;
            if (data.success) {
                console.log(data); //use $log.info() instead
                $scope.templates = data.templates;
            }
    });
});

Check these links for more info:

Community
  • 1
  • 1
JonyD
  • 1,237
  • 3
  • 21
  • 34
0

I would probably put everything in a single service (templateService). I'm not sure if the bodyOption belongs there but for now I would just put it there. Then I would move the load/save template function to the service.

You could probably do more, for instance, your might set the $scope.templateService = templateService and in your html use templateService.bodyOptions/templates directly.

Also, you could probably move the save.success from the controller to the service aswell.

tplApp.service('templateService', function($http, $routeParams) {

var self = this;
this.template = {};

this.loadTemplate = function() {
   $http.get(baseUrl+'templates/get_template/' + $routeParams.template_id)
       .success(function(data) {
           self.template = data;
       });
};

this.saveTemplate = function() {
    return $http({
        method: 'POST',
        url: baseUrl + 'templates/save',
        data: $.param(self.template),
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    });
};

this.bodyOptions = {
    plugins: 'link image code',
    toolbar: 'bold, italic, underline,  alignleft, aligncenter, alignright, alignjustify, styleselect, bullist, numlist, outdent, indent, removeformat, mybutton, code',
    height: 300,
    menubar: false,
    statusbar: false,
    setup: function(editor) {
        editor.addButton('mybutton', {
            type: 'menubutton',
            text: 'Variables',
            icon: false,
            menu: [
                {text: 'Candidate Name', onclick: function() {editor.insertContent('%name%');}},
                {text: 'Company Name', onclick: function() {editor.insertContent('%company-name%');}},
                {text: 'Today\'s Date', onclick: function() {editor.insertContent('%date%');}},
                {text: 'Your Name', onclick: function() {editor.insertContent('%your-name%');}},
            ]
        });
    }
};
});

tplApp.controller('editAndAddController', function ($scope, templateService){
$scope.template = templateService.template;
$scope.bodyOptions = templateService.bodyOptions;

if(edit) {
    templateService.loadTemplate();
}

$scope.saveTemplate = function() {
    templateService.saveTemplate()
        .success(function(data) {
            $scope.message = data.message;
            if (data.success) {
                console.log(data);
                $scope.templates = data.templates;
            }
        });
};
});

Ideally your controller would probably look like this:

tplApp.controller('editAndAddController', function ($scope, templateService){
$scope.templateService = templateService;

if(edit) {
    templateService.loadTemplate();
}
});

Heads up! This is just example, code is not tested!

Oli
  • 1,132
  • 1
  • 12
  • 26