Troels Larsen
Troels Larsen

Reputation: 4631

AngularJS: Reading JSON in controller

I am having some problems exposing a field on my AngularJS controller. I have a webservice returning a JSON 'owner' object, with a field called 'Cave'. If this field has a null (or empty/whitespace) value, I want to hide an element in my view using ng-hide. To achieve this, I hope to expose the field 'hideCave' from the controller, shown in its entirety below:

function OwnerController($scope, OwnerFactory, $routeParams) {
    if ($scope.owner == null) {
        $scope.owner = OwnerFactory.getOwner($routeParams.id);
        //$scope.hideCaveat = $scope.owner.Cave == undefined;

        //Outputs 'Hide: {}?undefined'
        alert('Hide: ' + JSON.stringify($scope.owner) + '?' + $scope.hideCaveat); 
    }

    $scope.someButton = function () {
        //Outputs full JSON string when clicked
        alert('Hide: ' + JSON.stringify($scope.owner) + '?' + $scope.hideCaveat); 
    }
}

myApp.factory('OwnerFactory', function ($http) {
    return {
        getOwner: function (id) {
            var url = 'api/Owner/' + id;
            return $http.get(url)
            .then(function (response) {
                return response.data;
            });
        }
    }
});

My data loads fine, but I can't get a value out of $scope.owner.Cave until I add a ng-click event any trigger it.

Example JSON return from web service:

{"FirstName":"David","LastName":"Lynch","Street":"Oak Dr. 7","ZipCode":"90210","Town":"Beverly Hills","Email":"","Cave":"Do not sell this man any more drugs"}

What am I doing wrong since I don't get the value?

Is my issue related to the fact I'm creating a global function for my controller? Should I use myApp.controller instead?

Upvotes: 2

Views: 3468

Answers (4)

EnigmaRM
EnigmaRM

Reputation: 7632

You should be able to just access it as you would any other object

<div class="alert" ng-show="owner.Cave">{{owner.Cave}}</div>

Plunker In the plunker I just hardcoded the data.

Upvotes: 2

user1375096
user1375096

Reputation:

add a watch at beginning of your controller, so "hideCaveat" is always there.

function OwnerController($scope, OwnerFactory, $routeParams) {
  $scope.$watch( 'owner.Cave', function(cave) {
    if (cave && cave.length > 0) {
      $scope.hideCaveat = false;
    } else {
      $scope.hideCaveat = true;
    }
  });
  ...

Upvotes: 1

DeadAlready
DeadAlready

Reputation: 3008

Have you tried using ng-show="owner.Cave" in your template? It should work fine.

The reason why you get an empty object alerted is that the $http.get is not a synchronous function. It returns a promise - so by the time you reach alert you still only have the promise. Only once it has been resolved - such as before you click the button, do you see the actual data.

Upvotes: 2

mpm
mpm

Reputation: 20155

myApp.factory('OwnerFactory', function ($http) {
    return {
        getOwner: function (id) {
            var url = 'api/Owner/' + id;
            return $http.get(url);
        }
    }
});

and

$scope.owner = OwnerFactory.getOwner($routeParams.id).then(function(data){
     $scope.hideCaveat = data.owner.Cave == undefined;
});

since getOwner returns a promise.

edit

better use ng-hide or ng-show on the data you want to show or hide

<div ng-show="owner.Cave">cave infos</div>

Upvotes: 1

Related Questions