2

I'm trying to display the contents of a div based on the response from an $http service. The AJAX call works fine and is not the issue here. However, I am unable to update the controller variable that I would like (intFlag) to obtain the desired behavior. I thought creating a global variable would resolve the issue even though I didn't want to do that.

Here is a similar question: (AngularJS : ng-show usage), but the solution, which I've seen in many other places, does not seem to work for me. This seems like a fairly standard procedure. Initially, I thought it was just a scope issue, but even the global variable attempt isn't working. This may be because the view doesn't update in response to changes in global variables. I'm still learning Angular.

<html ng-app="myapp">
<head>
<script type="text/javascript">
var intFlag = 0; 

var app = angular.module('myapp', []);
app.controller('AController', function ($scope, $http) 
{   //I've tried: var this.intFlag = 0; here already
    this.CreateUser=function()
    {   //scope changes here, right?
        $http({
        method: 'POST',
        url: 'some url', //pseudocode
        data: someData, //pseudocode
        headers: { 'Content-Type': 'application/x-www-form-urlencoded'} 
        }).then(function successCallback(response) 
            {   intFlag = 1; //global variable
                //Ideally I want to update a variable that is in the scope for the controller
            }, function errorCallback(response) {
        });
    };
});

</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5 /angular.min.js"></script>

</head>
<body ng-controller="AController as Ctrl">

<div>
<button type="button" ng-click="Ctrl.CreateUser()" >Create User</button>
<div ng-show="intFlag === 1">
    <p>Congratulations!</p>
</div>
</div>
</body>
</html>
Daniel Cottone
  • 4,257
  • 24
  • 39
  • Angular expressions are always evaluated on the scope. Global variables are inaccessible to them. And they should be avoided anyway. Also, JavaScript has booleans. Use a boolean for a true/false value. Not a number. – JB Nizet Jun 30 '16 at 19:45
  • Thanks for the information about global variables. I'd been told to avoid them in angular, but never why. – Pablo Francesca Jun 30 '16 at 20:18
  • You should avoid them everywhere. Using global variables leads to spaghetti code, where every possible line of code can potentially read or modify this global state, making bugs very hard to diagnose, and tests hard to write. See http://stackoverflow.com/questions/10525582/why-are-global-variables-considered-bad-practice – JB Nizet Jun 30 '16 at 20:21

4 Answers4

2

You need to add that variable to controller context(this) as you are using controllerAs then use it with controller alias like Ctrl.intFlag. Additionally I'd say that remove $scope dependency from controller which doesn't make sense to mix $scope & this together.

Markup

ng-show="Ctrl.intFlag"

Code

var app = angular.module('myapp', []);
app.controller('AController', function ($http) 
{
    var self = this;
    self.intFlag = intFlag;
    self.CreateUser=function()
    {   //scope changes here, right?
        $http({
        method: 'POST',
        url: 'some url', //pseudocode
        data: someData, //pseudocode
        headers: { 'Content-Type': 'application/x-www-form-urlencoded'} 
        }).then(function successCallback(response) 
            {   self.intFlag = 1;//global variable
                //Ideally I want to update a variable that is in the scope for the controller
            }, function errorCallback(response) {
        });
    };
});
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
2

You need to have a controller context variable such as 'self':

Controller

app.controller('AController', function($scope, $http) { //I've tried: var this.intFlag = 0; here already
  var self = this;
  self.intFlag = 0;

  this.CreateUser = function() { //scope changes here, right?
    $http({
      method: 'POST',
      url: 'some url', //pseudocode
      data: someData, //pseudocode
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    }).then(function successCallback(response) {
      self.intFlag = 1; //global variable
      //Ideally I want to update a variable that is in the scope for the controller
    }, function errorCallback(response) {});
  };
});

And then reference the variable on the context like this:

HTML

<div ng-show="Ctrl.intFlag === 1">
jbrown
  • 3,025
  • 1
  • 15
  • 22
1

You're not attaching intFlag to scope.

$scope.intFlag = 1;
Daniel Cottone
  • 4,257
  • 24
  • 39
  • 1
    This won't work since he's using the ControllerAs syntax. – jbrown Jun 30 '16 at 19:58
  • @jbrown Yes, it will work. controllerAs just puts the controller itself in the scope. All expressions are still evaluated on the scope, and the scope is still there. – JB Nizet Jun 30 '16 at 20:06
  • @JBNizet - you're right ... I just don't normally see the 2 mixed like that – jbrown Jun 30 '16 at 20:08
-1

Pankaj Parker's contribution (which I had seen elsewhere, but still don't fully understand) resolved the issue.

The following code changes obtain the desired behavior.

<html ng-app="myapp">
<head>
<script type="text/javascript">
    var app = angular.module('myapp', []);
    app.controller('AController', function ($scope, $http) 
        {   this.intFlag = false; //new code
            this.CreateUser=function()
            {   var self = this; //new code
                $http({
                method: 'POST',
                url: 'some url',
                data: someData,
                headers: { 'Content-Type': 'application/x-www-form-urlencoded'} 
                }).then(function successCallback(response) 
                    {   self.intFlag = true; //new code
                    }, function errorCallback(response) {
                });
            };
    });

</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>

</head>
<body ng-controller="AController as Ctrl">
<div>
    <button type="button" ng-click="Ctrl.CreateUser()" >Create User</button>
<div ng-show="intFlag">
    <p>Congratulations!</p>
</div>
</div>
</body>
</html>
  • There is no point in answering your own question with the same answer as the one given by someone else, especially if you make a mistake in the answer and make it incorrect. – JB Nizet Jun 30 '16 at 20:22