0

Below added my controller code. I want to access value of $scope.FCGId ....... How can access this variable?

 angular.module('hotelApp.controllers')
     .controller('menuCtrl', ['$scope','menu'
         function($scope,'menu') {

             $scope.categories = [];
             $scope.FCGId = 0

             $scope.items = [];

             $scope.getCategories = function() {
                 menu.getCategories().success(function(data) {
                     $scope.categories = data;
                     $scope.FCGId = data['rows'][0].GRPCOD;

                 });
             }

             $scope.getItems = function(gropuId) {
                 menu.getItems(gropuId).success(function(data) {
                     $scope.items = data;
                     console.log(data);
                 });
             }

             $scope.$on('$ionicView.afterEnter', function() {
                 $scope.getCategories();
                 console.log($scope.FCGId);
                 $scope.getItems($scope.FCGId);

             });
         }
     ]);

From, above code returns 0 instead of value updated in getCategories() function.

9
  • Is all this code belongs to same controller? Commented Jun 29, 2015 at 10:34
  • yes .. from same controller Commented Jun 29, 2015 at 10:35
  • Where do you need to access that? Are you talking about in the HTML? Commented Jun 29, 2015 at 10:35
  • Seems to be a timing issue. Are you sure your variable is filled with the result data from your getCategories() function when you call your log? Commented Jun 29, 2015 at 10:35
  • If you add a console log for $scope.FCGId in getCategories() and/or getItems(), what do you get? Commented Jun 29, 2015 at 10:36

3 Answers 3

1

Well

$scope.getCategories function is giving asynchronous call in below event

$scope.$on('$ionicView.afterEnter', function() {
                 $scope.getCategories();
                 console.log($scope.FCGId);
                 $scope.getItems($scope.FCGId);

             });

when you call $scope.getCategories(), this asynchronous call is given.

But script is not waiting for completion of that call. And script access $scope.FCGId variable in console.log($scope.FCGId); without initialization because asynchronous cal is not completed.

Solution to this.

Either you call $scope.getCategories function at the start of controller as initialization part or you should return promise from $scope.getCategories function or use promise in another way as per your requirement.

EDIT CODE.

Defined $scope.getCategories as follow

inejct $q in your controller.

var defer = $q.defer();       
$scope.getCategories = function() {
                 menu.getCategories().success(function(data) {
                    $scope.categories = data;
                   // $scope.FCGId = data['rows'][0].GRPCOD;
                    defer.resolve(data['rows'][0].GRPCOD);  
                    return defer.promise;

                 });
             }  

and event handling in this way

 $scope.$on('$ionicView.afterEnter', function() {
                 $scope.getCategories().then(function(successData){
                 $scope.FCGId = successData
                  console.log($scope.FCGId);
                 });

                 $scope.getItems($scope.FCGId);

             });    

Solution -2. Also there is no dependency while giving call to $scope.getCategories function so you can call it at the starting of comptroller.

Same you can do for the call to $scope.getItems.

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

6 Comments

but it is same as we whole function in $scope.on, but i don't want to change structure and want result it is possible?
I think defer should be declared inside the function and the promise should be return as soon as the ajax call is fired (aka putting outside of success)
Yes, @lcycool , var defer can be declared outside function and inside this function, we can define this variable defer = $q.defer();
Can you show me an example of defer declared outside of function?
var defer ; $scope.getCategories = function() { menu.getCategories().success(function(data) { $scope.categories = data; defer = $q.defer() // $scope.FCGId = data['rows'][0].GRPCOD; defer.resolve(data['rows'][0].GRPCOD); return defer.promise; }); }
|
1

Your problem happens because javascript almost always runs faster than asynchronous call returns, so your $scope.getItems always calls before $scope.getCategories returns.

To strictly order the API calls you need a powerful construct called promise. There should be a lot of resources out there, just google "angular promise" and you're good =)


Edit: Actually making use of the success function is the most straight forward way to do this

$scope.getCategories = function() {
    menu.getCategories().success(function(data) {
        $scope.categories = data;
        $scope.FCGId = data['rows'][0].GRPCOD;

        $scope.getItems($scope.FCGId);  // to here
    });
}

$scope.getItems = function(gropuId) {
    menu.getItems(gropuId).success(function(data) {
        $scope.items = data;
        console.log(data);
    });
}

$scope.$on('$ionicView.afterEnter', function() {
    $scope.getCategories();
    console.log($scope.FCGId);
    // $scope.getItems($scope.FCGId);  // move this line
});

By this way you don't have to deal with all those $q and d's. And promise-antipatterns.

2 Comments

yes using promise it is possible but it is same as we whole function in $scope.on, but i don't want to change structure and want result it is possible?
slight change to structure
0

Seems like your menu.getCategories() is an asynchronous execution block, and because of deferred execution, you are getting 0 as the value of $scope.FCGId.

You can pass a function as the second parameter to the getCategories function, that will get executed and perform necessary assignments and further calls.

$scope.setFCGValue = function(data) {
     $scope.categories = data;
     $scope.FCGId = data['rows'][0].GRPCOD;
     $scope.getItems($scope.FCGId);
};

$scope.$on('$ionicView.afterEnter', function() {
     menu.getCategories().success($scope.FCGValue);
});

What we are doing is passing our custom function, that will be executed after the getCategories() part.

2 Comments

but it is same as we whole function in $scope.on, but i don't want to change structure and want result it is possible?
You should then take a look at deferred API of AngularJs $q.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.