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.

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.