Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

Achieving Reusability using JavaScript closure, apply function and Angular’s Service

4.67/5 (4 votes)
10 Oct 2016CPOL1 min read 9.7K  
Reusability using JavaScript closure, apply function and Angular’s Service

Introduction

  • Task: Give a confirmation pop-up on deletion of every component in the project.
  • Challenge: All different components have different delete functions with different set of parameters.

Using the Code

Solution

Step 1

Create an Angular Service and common confirmation popup HTML as we want this similar confirmation message functionality to be shared throughout the Angular application.

Angular Service

JavaScript
AngularApplicationModulePointer.service('ConfirmationService', function (ngDialog) {

    //Settings of the Delete Confirmation Popup
    var DeletePopUpConfiguration = {
        template: '/app/views/confirmationPopup.html',
        controller: function ($scope, ConfirmationService) {
                        $scope.confirmationPopupModel = {
                PopUpTitle: ConfirmationService.PopUpTitle, 
                ConfirmationMessage: ConfirmationService.ConfirmationMessage,
                callbackFuncExecute: function () { ConfirmationService.callbackFuncExecute(); }, 
                closeConfirmationPopup: function () { ConfirmationService.closeConfirmationPopup(); },
                ConfirmButtonText: ConfirmationService.ConfirmButtonText, 
                DenyButtonText: ConfirmationService.DenyButtonText
            };
},
        className: 'ngdialog-theme-plain',
        width: 500,
        showClose: true,
        closeByDocument: false,
        closeByEscape: false,
    };

//Variable to choose the popup confirmation message, is in fact the keyword of MessageDictionary object
    this.messageType = '';
    
//Dictionary of all popup confirmation messages
    var MessageDictionary =
    {
        MessageA: "Are you sure you want to delete component A?",
        MessageB: "Are you sure you want to delete component B?",
    };
//To select validation messages based on the keywords
    var getMessage = function (messageType)
    {
        var message = MessageDictionary[messageType];
        return message;
    };

//Open common confirmation Message Pop-up and set/bind all the properties and functions
//parameters : is Array of input parameters that the delete callback function, 
//specific for that module, accepts as input. It should be in the same order 
//as the input parameters of the delete function.
//The callback function comes first and the array of parameters comes second always

    this.openConfirmationPopup = function (callbackFunction, callbackFunctionparameters) {
        this.Message = getMessage(this.messageType);
        this.callbackFunction = callbackFunction;
        this.funcParameters = callbackFunctionparameters;
        this.DeletePopUpPointer = ngDialog.open(DeletePopUpConfiguration);
    };

//To execute the Delete callback function of the module which passed the control here
    this.callbackFuncExecute = function () {
        var callbackFunction = this.callbackFunction;
        var funcParameters = this.funcParameters;
        callbackFunction.apply(this, funcParameters);
       this.DeletePopUpPointer.close();
    };

    //Close the common confirmation Message Pop-up
    this.closeConfirmationPopup = function () {
        this.DeletePopUpPointer.close();
    }; 
});

/app/views/confirmationPopup.html

HTML
<div>
<div class="row">
                <div class="col-lg-12 col-md-12 col-sm-12">
                    <h4>{{confirmationPopupModel.PopUpTitle}}</h4>
                </div>
            </div>
            <div class="row">
                <div class="row">
                    <div class="col-lg-12 col-md-12 col-sm-12">
                        <p style="line-height: 20px;">
                            {{confirmationPopupModel.ConfirmationMessage}}<br />
                        </p>
                    </div>
                </div>
            </div>
            <div>
                <button class="btn btn-blue" type="button" 
                ng-click="confirmationPopupModel.callbackFuncExecute()">
                {{confirmationPopupModel.ConfirmButtonText}}</button>
                <button type="button" class="ngdialog-button btn btn-light-grey" 
                ng-click="confirmationPopupModel.closeConfirmationPopup()">
                {{confirmationPopupModel.DenyButtonText}}</button>
            </div>
        </div>

Step 2: Using the Created Angular Service

ComponentA.html

JavaScript
<button type="button" title="Delete" class="btn btn-blue" 
ng-click="vm.ComponentAModel.ConfirmDelete(param1,param2)">Delete</button>

ComponentACtrl.js

JavaScript
AngularApplicationModulePointer.Controller('ComponentAController', 
['$scope', '$q', 'ngDialog','ConfirmationService',
function ComponentAController($scope, $q, ngDialog, ConfirmationService) {
var vm= this;
vm.ComponentAModel= {

// Component delete function of this controller.
        DeleteFunction: function (param1,param2) {
// code to delete component
},

// show popup When delete button is clicked .
        ConfirmDelete: function (param1,param2) {
            ConfirmationService.PopUpTitle = "Delete Component A";
            ConfirmationService.messageType = "MessageA";
            ConfirmationService.ConfirmButtonText = "Yes";
            ConfirmationService.DenyButtonText = "No";
            //Array of input parameters that the delete function "vm.ComponentAModel.DeleteFunction" 
            //accepts as input, in the same order as the function definition.
            var paramArray = [param1,param2];
            //Input parameters passed are the delete function to execute and the 
            //array of parameters that delete function accepts. 
            //The function Name comes first and the array of parameters comes second        
 ConfirmationService.openConfirmationPopup(vm.ComponentAModel.DeleteFunction,paramArray);
                   },
}

return vm;
});

The code flow is:

  1. When the delete button on the ComponentA.html is clicked, the function sets the Pop-up title, confirmation message type and Button texts, using the Angular Service variables.
  2. Then in paramArray, we capture all the parameters that the Delete function accepts in the same order of input parameters of the Delete Function.
  3. Then we call the function to open Confirmation Pop-up with delete function as closure and paramArray as second input parameter.
  4. Now the open Pop-up function will set/bind all the fields and functions with the confirmation Pop-up. Then opens the pop-up.
  5. If the User clicks on “Yes”, the callbackFuncExecute() will be called.
  6. The callbackFuncExecute() now using the JavaScript apply() binds the callbackFunction (the DeleteFunction) with the funcParameters(the paramArray) and executes the DeleteFunction.

Note: ngDialog is the third party js used for pop-up.

Points of Interest

Combination of Angular Service, JavaScript closure and apply() provided us the freedom to execute different signatured functions outside their scopes.

History

  • Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)