Search code examples
javascriptangularjscallbindcurrying

JavaScript/Angular borrowing a function and appending parameters


Lets say I have a service function that takes a static param and a second custom param that varies based on the controller it is injected in. I want my controller/view to call this service function without having to write a custom method in the controller itself just to pass that custom parameter. I'm not sure if this technique involves currying, call, bind, or apply.

.service('ExampleSvc', function() {
  this.call = function(param, controller) {
    console.debug(param, controller);
  }
})

.controller('FirstCtrl', function($scope, ExampleSvc) {
  $scope.call = ExampleSvc.call; // magic happens here

  // avoid writing below
  $scope.call = function() {
    ExampleSvc.call('param', 'FirstCtrl');
  }
});

.controller('SecondCtrl', function($scope, ExampleSvc) {
  $scope.call = ExampleSvc.call; // magic happens here

  // avoid writing below
  $scope.call = function() {
    ExampleSvc.call('param', 'SecondCtrl');
  }
});

Solution

  • As I understand You need to use service in view, so easiest is to set $scope variable as service:

    $scope.service=$service;
    

    So every method from service can be called directly from view, without creating any special $scope methods.

    If needed is only one method, and we need to change its paramater then:

    $scope.call = function(){ ExampleSvc.call.call(this,'param', 'FirstCtrl'); };
    

    I created anonymous functiom which is calling our call ( second call is builded in prototype method for calling functions ) method with desirable parameters.

    But if Your service is different on every usage better approach is to return in service constructor. So we can use new keyword every time and have new object of service.

    //service code

    return function(controller){
    
      this.controller=controller;
    
      //here methods ...
    
    };
    

    //controller code

    $scope.service=new service("ControllerName");
    

    So in this approach we can have different objects of service for every usage, so it is go around of singleton which is service tipical. I will try to show example of this approach:

    var app=angular.module("app",[]);
    
    app.controller("cont1",function($scope,person){
    
      $scope.p=new person("Tom","Hanks");
      
    });
    
    app.controller("cont2",function($scope,person){
    
      $scope.p=new person("Will","Smith");
       
    });
    
    //our service which returns constructor
    app.service("person",function(){
    
      return function(name,surname){
        
        this.name=name;
        this.surname=surname;
        
        
        this.getName=function(){
        
          return this.name;
          
        };
        
        this.getSurname=function(){
        
          return this.surname;
        };
        
      };
      
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="app">
      
      <div ng-controller="cont1">
      
          <span> Person is: <b>{{p.getName()}} {{p.getSurname()}}</b></span>
      </div>  
      
      <div ng-controller="cont2">
          <span> Person is: <b>{{p.getName()}} {{p.getSurname()}}</b></span>
      </div>  
      
      
    </div>  

    So we can use our service in different way by creating new objects. Sending it to scope give possibility to run configured object directly there.