Why is the $scope variable value not being updated in Angular JS controller?

My controller code snippet is shown below. I am trying to access the value of $scope.FCGId. How can I 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);

             });
         }
     ]);

The code above is returning 0 instead of the updated value from the getCategories() function.

Answer №1

Alrighty

$scope.obtainCategories function initiates an asynchronous call during the event below

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

             });

When $scope.obtainCategories() is invoked, it triggers an asynchronous request.

However, the script does not wait for this call to finish. It attempts to access the $scope.FCGId variable in console.log($scope.FCGId); without proper initialization due to the incomplete asynchronous call.

A solution for this issue would be:

Either calling $scope.obtainCategories function at the beginning of the controller as an initialization step, or returning a promise from the $scope.obtainCategories function, or utilizing a promise in an alternative manner based on your specific needs.

CODE MODIFICATION.

Define $scope.obtainCategories in the following manner

Inject $q into your controller.

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

                 });
             }  

and handle the event like this

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

                 $scope.fetchItems($scope.FCGId);

             });    

Alternative Solution -2. Since there are no dependencies in calling the $scope.obtainCategories function, it can be executed at the beginning of the controller.

The same approach can be applied to the call to $scope.fetchItems as well.

Answer №2

The issue you're facing is due to the fact that JavaScript typically runs faster than asynchronous calls return, causing your $scope.getItems function to execute before $scope.getCategories has completed.

To ensure the order of API calls, you can utilize a powerful concept known as promises. There are plenty of resources available on the topic, simply search for "angular promise" to learn more =)


Update: Another straightforward approach is to leverage the success function:

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

        $scope.getItems($scope.FCGId);  // this line
    });
}

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

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

By following this method, you can avoid dealing with $q and other promise-related complexities.

Answer №3

It appears that the menu.getCategories() function is running asynchronously, resulting in a delayed execution and causing the $scope.FCGId to be set as 0.

To address this issue, you can provide a callback function as the second parameter to the getCategories function. This callback function will handle the necessary assignments and subsequent 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.setFCGValue);
});

By passing a custom function as a callback, we ensure that the required operations are carried out after the completion of the getCategories() function.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing dynamic variables in Angular Translate Rails: a tutorial

Has anyone encountered issues with passing variables from the gem angular-translate-rails to Rails? My setup consists of a backend in Rails and a front end in AngularJS. Here's what I've attempted so far: 1. Inside the controller: $translate(& ...

Maintain the structure of the slick slider during transitions

I am working with the slick slider and aiming to achieve a specific layout for the slider itself. What I require is a structure that looks like this: div div div div div I have managed to implement this design successfully, bu ...

How come my links aren't initiating jQuery click events?

Today, I decided to experiment with jQuery and encountered an issue. On my webpage, there are multiple links displayed in the format shown below: <a class="a_link" id="a_id<#>" href="#">Click me</a> The value <#> is a number gener ...

Creating a Cascading State and City Dropdown Using Knockout JS and JSON Data

When the user selects a state from two fields, state and city, a call is sent to the server returning JSON data. This data needs to be used to update the city field in knockout, but there seems to be an issue with the syntax of getting the ajax data. Here ...

What causes discrepancies between jQuery set attributes and .html() output?

In an attempt to set attributes on HTML snippets, I am aiming to repopulate a form with previously entered values. Despite using .attr() to set the attributes, they do not appear after using .html(). For reference, I have provided a simple example here: h ...

Turn off the ability to view the content of .css and .js files within the browser

Earlier, I inquired about how to disable file and folder listing and discovered that it can be achieved using a file named .htaccess. To disable folder listing, I entered Options -Indexes in the .htaccess file located in the parent folder. Additionally, to ...

Is Next.js the Ultimate Serverless Rendering Tool with Cloudflare Workers?

I am currently using Next.js version 9 and I am interested in utilizing Next's serverless deployment feature by integrating my application with Cloudflare Workers. According to the documentation for Next.js, all serverless functions created by Next f ...

A jquery class for styling with CSS

I am looking to add a CSS class to a gridview. I attempted to use this style from a reference link, so I implemented the following code snippet: $(function () { $('[ID*=search_data]').on('click', function () { var fromda ...

Gaining entry to a JSON object within an array

I've completed various courses on JSON and put in a lot of effort to troubleshoot this bug. However, it seems that my question is too specific and I require a practical example. JSON { "date": "2017-10-15", "league": "NHL", "odds": "spreads", ...

Using an id as the attribute value for a React ref

I have a question about referencing DOM nodes in a component. Currently, I am able to get the nodes and children using the following code: export class AutoScrollTarget extends React.Component { constructor(props) { super(props); this ...

I am facing difficulties in showing the data in my Ionic view when attempting to connect to my php API

Attempting to utilize a PHP API for data display is posing a challenge. The PHP side appears to be functioning correctly, as the data is being displayed through echo. However, encountering an error when trying to fetch the data in the Ionic view using http ...

Providing static content within the generated code structure by Yeoman for the Angular Fullstack framework

I'm sticking to the code structure generated by Yeoman for an Angular fullstack application. The issue I'm facing is how to include a script called core.js in a file named app.html. <script src="core.js"></script> I can't fi ...

Is there a way to choose all elements in the Bootstrap pagination code using JavaScript?

Recently, I've been working on a website with Bootstrap, and I encountered an issue with the overflow scroll bar that I had to hide using CSS. To navigate the pagination with the mouse wheel, I've been experimenting with JavaScript. I found that ...

What is the proper way to bind CoreUI's CSwitch component?

I am trying to incorporate the CSwitch component into a DevExtreme data grid. While the DxSwitch component functions correctly, I am unable to get the CSwitch to work properly. It seems like I might be using the wrong binding. Could that be the issue? < ...

JavaScript functions are not being triggered when the submit button is clicked

I am facing an issue where the form buttons are not triggering functions in my React application. The post request is being made using Axios. Could this be related to the structure of my components? Or perhaps it has something to do with file naming conven ...

How to Build a Custom Toolbar with Left and Right Aligned Elements using React.js and Material UI

Struggling with updating the toolbar on my website. Wanting the site name and logo on the left side, while login/sign-up buttons fixed to the right. Logo and title are in place, but can't get buttons to stay on right margin. Here's the code: func ...

Display the personalized list of user items on the MERN dashboard

I'm currently developing a React booking platform that interacts with my backend through a Rest API using axios and redux. My challenge now is to display personalized reservations and rooms for each user on the website. However, I'm facing an iss ...

What is the best way to retrieve an ng-model parameter within a controller?

I'm working on implementing a PUT method in my controller and need to bind the new value back to it. I've tried: <div ng-app="myApp" ng-controller="personCtrl"> <form> First Name: <input type="text" ng-mod ...

What is the process for exporting data from MongoDB?

Recently, I created a web application for fun using Handlebars, Express, and Mongoose/MongoDB. This app allows users to sign up, post advertisements for others to view and respond to. All the ads are displayed on the index page, making it a shared experie ...

Understanding the process of unmarshalling an array within a POST request

I am attempting to send an array of JSON data with a POST request to an API server. However, I keep encountering the following error: cannot unmarshal array into Go value of type models.UserRequest Despite trying to unmarshal the data using a factory and ...