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>');
      });



    }]);

  })();

1 Answer 1

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
});
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you. How would it be if I'd like to use $scope?
Thanks. How would I make the expression with $scope? {[{outputCtrl.verb["@attributes"]["name"]}]} only works with this.verb = VerbFactory.getJSON();.
{{ 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"] }}
$scope does not seem to work with ControllerAs. When I remove the alias and use regular syntax, it works.
|

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.