1

Trying to make a simple example with an AngularJS service.

I want to have some variables and functions in my data model ( service ) and through the controller, expose them and bind them to the view.

The problem is that the controller/view gets a new instance of the model somehow, and I can't really see how this is useful because I want to use other controllers/views to see the same data/API of the same service, not a new instance every time.

Here is an example on plunker : http://plnkr.co/edit/AKZLaT2HrkBPMkICsski?p=preview

/*****script.js******/
var app = angular.module('app',  []);

app.service('myService', function() {

  // my data here
  var text = 'text',
      text2 = 'text2';

  // my function here
  var copyText = function(){
      console.log('BEFORE text: '+ text + ' text2: ' + text2);
      text2 = text;
      console.log('AFTER text: '+ text + ' text2: ' + text2);
  };

  // expose my variables/API here
  return {
      text: text,
      text2: text2,
      copyText: copyText
  };
});

app.controller('myCtrl', [ '$scope', 'myService', function($scope, myService){

  $scope.myService = myService;

}]);


/*****index.html******/
...
  <div ng-controller="myCtrl">
    <h1>angular service exposure</h1>
    <input type="text" ng-model="myService.text">
    <p>text: {{ myService.text }}</p> 
    <button ng-click="myService.copyText()">copy text to text2</button>
    <p>text2: {{ myService.text2 }}</p> 
  </div>

if you open console, when you press the button you will see the 'real' values of the model, before and after the copying of text to text2. Which are not the ones I see in the view from the controller...

3 Answers 3

2

See my edit.

I did some changes, put ng-model as parameter to copyText():

 <div ng-controller="myCtrl">
    <h1>angular service exposure</h1>
    <input type="text" ng-model="myService.value">
    <p>text: {{ myService.text }}</p> 
    <button ng-click="myService.copyText(myService.value)">copy text to text2</button>
    <p>text2: {{ myService.value }}</p> 
  </div>

JS

var app = angular.module('app',  []);

app.service('myService', function() {

// my data here
var text = 'text',
    text2 = 'text2';



// my function here
var copyText = function(value){

  console.log('BEFORE text: '+ text + ' text2: ' + text2);
  text2 = value;
  console.log('AFTER text: '+ text + ' text2: ' + text2);
};

// expose my variables/API here
return {
    text: text,
    text2: text2,
    copyText: copyText
  };
});



app.controller('myCtrl', [ '$scope', 'myService', function($scope, myService){

  $scope.myService = myService;

}]);

Hope it will help you

Sign up to request clarification or add additional context in comments.

6 Comments

well, this is not what I'm looking for. You made a new function inside the controller to call the one from the service. What does this change from binding it to the element? It's still the same call, right? And second, you pass a new variable 'sometext' to make the changes to text2. I want to have access to the same two variables in the service from any controller, not make new ones in each controller. Even this example would not work with two controllers I guess, each ones would see a different 'text' and 'text2' variable... Thanks for your time anyway.
see my changes, pass model as parameter into method
I don't think you can write myService.value and be sure that service has your new value. You can use $rootScope or broadcast to tell to all controllers about change
I get that you can use the model in the view to pass something to the service, but the project I want to do has a much more complex model than that, so passing everything from views to services and back, will be a mess... So I want to make the model data and their API once, and then have it accessible ( the same singleton data and API ) from different controllers which will be connected to different views. Just trying to find the best way to do this.
Hmmm, to pass data to service without encapsulation doesn't seems as API. Let's wait someone else who knows how to help you
|
1

Found the problem, I think.

This function inside the service ( or factory ) is a constructor, so inside any function we make, we must use 'this' to access the new instance objects.

So the function becomes :

// my function here
var copyText = function(){
  console.log('BEFORE text: '+ this.text + ' text2: ' + this.text2);
  this.text2 = this.text;
  console.log('AFTER text: '+ this.text + ' text2: ' + this.text2);
};

Comments

0

In fact if you want to use a service you must link your function to "this".

The return statement is only for factory.

var app = angular.module('myApp', []);

app.factory('testFactory', function(){
    return {
        hello: function(text){
            return "Hello " + text;
        }
    }               
});

app.service('testService', function(){
    this.hello= function(text){
        return "Hello " + text;
    };         
});

The difference is not just syntax!

All angulars providers like Value,Constant,Service or Facotry are singletons.

If you use a service it's the instance of this service that is return. If you use a factory is the value of the instance that is return.

I hope it helps !

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.