0

The main thing I want to do here is:

  1. When the form is submitted, a http get request will be done (VerbController)
  2. On success, a JSON string is returned
  3. I copy the JSON string into a factory object (called VerbFactory)
  4. I want to output the content of the JSON string in a div through another controller (OutputController), I took the attribute "name" as an example here.

To achieve this (point 4), I watched for a change in the VerbFactory object and when the JSON string after requesting gets loaded into the object, I want to store it in a variable of the OutputController, so that I can make an expression for it in my HTML.

But it does not work right now. It seems that this.verb is in another scope than the controller scope. I have difficulties understand the difference between $scope and this here, even though I have read a decent amount of articles about the difference between those two.

How do I solve this problem? Do I miss something obvious?

NB: I added some jQuery that puts the attribute "name" of the JSON into a debug div, and it works as expected. But the AngularJS expression {[{outputCtrl.verb["@attributes"]["name"]}]} does not work.

HTML:

<div class="container">
  <div class="row">
    <div id="debug" class="col-xs-12 col-sm-12">
    </div>
    <div class="col-xs-12 col-sm-12" ng-controller="OutputController as outputCtrl">
      {[{outputCtrl.test}]}
      {[{outputCtrl.verb["@attributes"]["name"]}]}
    </div>
  </div>
</div>

JS:

(function() {
    var app = angular.module('LG', []).config(function($interpolateProvider){
      $interpolateProvider.startSymbol('{[{').endSymbol('}]}');
    });

    app.factory("VerbFactory", function(){
      var json = {};
      var available = false;

      return {
        getJSON: function() {
          return json;
        },
        setJSON: function(newObj) {
          angular.copy(newObj, json);
          available = true;
        },
        isAvail: function() {
          return available;
        },
        resetAvail: function() {
          available = false;
        }
      };

    });

    app.controller("VerbController", ['$http', 'VerbFactory', function($http, VerbFactory){

      this.verb = "";

      this.requestVerb = function() {
        VerbFactory.resetAvail();
        var that = this;

        $http.get('/request/' + that.verb).
          success(function(data) {

            VerbFactory.setJSON(data);

          }).
          error(function() {

          });

        this.verb = "";
      };

    }]);

    app.controller("OutputController", ['$scope', 'VerbFactory', function($scope, VerbFactory){

      this.test = "Test!";
      $scope.$watch(VerbFactory.isAvail, function(){
        this.verb = VerbFactory.getJSON();
        $('#debug').append('<p>'+ this.verb["@attributes"]["name"] +'</p>');
      });



    }]);

  })();
maikovich
  • 368
  • 2
  • 3
  • 16

1 Answers1

1

this inside of $scope.$watch callback refers to the callback scope, not the outer scope of OutputController. Use var self = this to refer to the OutputController.

ControllerAs Syntax

OutputController.js

var self = this
$scope.$watch(VerbFactory.isAvail, function(){
  self.verb = VerbFactory.getJSON();
  //etc
});

Regular Controller Syntax

OutputController.js

$scope.$watch(VerbFactory.isAvail, function() {
  $scope.verb = VerbFactory.getJSON();
  //etc
});
Jesse Buitenhuis
  • 670
  • 4
  • 11
  • Thank you. How would it be if I'd like to use $scope? – maikovich Mar 11 '15 at 19:45
  • Thanks. How would I make the expression with $scope? {[{outputCtrl.verb["@attributes"]["name"]}]} only works with this.verb = VerbFactory.getJSON();. – maikovich Mar 11 '15 at 19:48
  • {{ outputCtrl.verb["@attributes"]["name"] }} should work just fine - $scope and this both bind to OutputController as outputCtrl. You could user regular Controller syntax instead of ControllerAs and just use {{ verb["@attributes"]["name"] }} – Jesse Buitenhuis Mar 11 '15 at 19:52
  • Check out http://stackoverflow.com/questions/11605917/this-vs-scope-in-angularjs-controllers – Jesse Buitenhuis Mar 11 '15 at 19:54
  • $scope does not seem to work with ControllerAs. When I remove the alias and use regular syntax, it works. – maikovich Mar 11 '15 at 19:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/72795/discussion-between-maikovich-and-jesse-buitenhuis). – maikovich Mar 11 '15 at 20:08