The controller leaps into action at the first opportunity, even before the factory has a chance

Can someone help me implement the solution provided in this answer to my scenario?

I am attempting to cache data using SQLite with the Cordova SQLite plugin. However, I'm facing an issue where my controller executes before my factory completes its execution. Below are the snippets of my controller and factory code. I have added alerts to track the sequence of execution. Ideally, I expect the alert sequence to be 1,2,3,4,5,6 but when I run the code, I get a sequence like 1,5,6,2,3,4.

angular.module('foo').controller('PriceListController',["$scope","$http","$stateParams","CURD","$q","DB", function($scope,$http,$stateParams,CURD,$q,DB) {

$scope.brand_id=Number($stateParams.id);
$scope.process=true;
$scope.pricelists=[];    
$scope.getBrandDocs= function(){
    var parameters=new Array(2);
    parameters[0]=$scope.brand_id
    parameters[1]=1;
    CURD.exc_query("select * from brand_docs where brand_id=? AND type=?",parameters)
        .then(function(price_lists) {
            alert("2");
            $scope.inter_pricelist=price_lists;
            console.log("Records from query call:"+JSON.stringify( $scope.inter_pricelist)); 

            $scope.deferred = $q.defer();    
            if ($scope.inter_pricelist){
                console.log("Found data inside cache", JSON.stringify($scope.inter_pricelist));
                $scope.deferred.resolve($scope.inter_pricelist);
                // alert(JSON.stringify( $scope.inter_pricelist));
                alert("3");

            } 
            else{
                $http.get('http://foo.com?brand='+ $scope.brand_id +'&type=price_list')
                .success(function(data) {
                    //alert("http call");
                    console.log("Received data via HTTP",JSON.stringify(data));
                    angular.forEach(data.data.info, function(value, key) {
                        var sql = "INSERT OR REPLACE INTO brand_docs(id, brand_id, name, file_url,type) VALUES (?, ?, ?, ?, ?)"; 
                        var parameters=new Array(5);
                        parameters[0]=value.id;
                        parameters[1]=value.brand_id;
                        parameters[2]=value.name;
                        parameters[3]=value.file_url;
                        parameters[4]=value.type;    
                        var result=DB.query(sql,parameters);
                    });

                    $scope.deferred.resolve(data.data.info);

                })
                .error(function() {
                    console.log("Error while making HTTP call.");
                    $scope.deferred.reject();
                });
        }

        return ($scope.deferred.promise).then(function(pricelists){
        alert("4");    
            return pricelists;
        },function(){});

    },function(){});  
  alert("5");  
};

$scope.pricelists=$scope.getBrandDocs();
alert("6"); 
}]);

// Here is the factory code

angular.module('foo').factory('DB', function($q, DB_CONFIG,$cordovaSQLite) {
    var self = this;
    self.db = null;

    self.init = function() {
        try{ 
            self.db =  window.sqlitePlugin.openDatabase(DB_CONFIG.name, '1.0', 'database', -1);
            angular.forEach(DB_CONFIG.tables, function(table) {
                var columns = [];
                angular.forEach(table.columns, function(column) {
                    columns.push(column.name + ' ' + column.type);
                });
                var query = 'CREATE TABLE IF NOT EXISTS ' + table.name + ' (' + columns.join(',') + ')';
                self.query(query);
                console.log('Table ' + table.name + ' initialized');
            });
        }
        catch(err){
        }

    };

    self.query = function(query, bindings) {
        bindings = typeof bindings !== 'undefined' ? bindings : [];
        console.log("Query:"+query+" bindings:"+ bindings);
        var deferred = $q.defer();

        self.db.transaction(function(transaction) {
            transaction.executeSql(query, bindings, function(transaction, result) {
                console.log("Query sucessfull :"+ query);
                console.log("Result of Query:"+ JSON.stringify(result));
                deferred.resolve(result);

            }, function(transaction, error) {
                console.log("Error:"+ JSON.stringify(error));
                deferred.reject(error);
            });
        });

        return deferred.promise;
    };

    self.fetchAll = function(result) {
        var output = [];

        for (var i = 0; i < result.rows.length; i++) {
            output.push(result.rows.item(i));

        }
         //console.log("RECORDS:" +JSON.stringify(output));
        return output;
    };

    self.fetch = function(result) {
        return result.rows.item(0);
    };

    return self;
})
.factory('CURD', function(DB) {
    var self = this;

    self.all = function(table_name) {
        return DB.query('SELECT * FROM '+table_name)
        .then(function(result){
            return DB.fetchAll(result);
        });
    };

    self.exc_query = function(query,parameters) {
        return DB.query(query,parameters)
        .then(function(result){
            return DB.fetchAll(result);
        });
    };

    self.getById = function(id,table_name) {
        return DB.query('SELECT * FROM '+table_name +' WHERE id = ?', [id])
        .then(function(result){
            return DB.fetch(result);
        });
    };

    return self;
});

Answer №1

When you invoke CURD.exec_query(), the query is queued and processing continues while it waits. This asynchronous behavior causes steps 4, 5, and 6 to be executed before steps 2 and 3 are alerted. The ".then()" method is only triggered after the query completes, resulting in the alert for steps 2 and 3.

It's important to note that getBrandDocs() will return before the .then() method is called. To ensure steps 4, 5, and 6 are executed after the query completes, consider emitting an event in the .then() method which can be asynchronously handled in the calling code.

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

How can I link a .json document to an autocomplete dropdown menu in AngularJS MVC?

I have a vast amount of city names stored in a .json file and I am looking for a way to bind all of these city names to my auto complete drop down list using Mvc AngularJS. Any suggestions on how to achieve this would be greatly appreciated. Thank you in ...

The issue with properly filtering a nested JSON object within an array in JavaScript

I am currently working on integrating a search input filter inside a dropdown menu that contains nested dropdown list items. The JSON data I receive from the API response is as follows: API response glPlmAsmt.category = { "page_size": 100, ...

Disabling pointer-events on material-ui textField input is ineffective

I have a material-ui textField input and I want to prevent the user from entering text by setting the css to pointer-events: none. However, this method does not work as expected. While I am aware that I can use the disabled={true} flag to disable the inpu ...

Utilizing a CASE statement in conjunction with a SELECT query in SQLite to filter out specific data from being

I attempted to address the issue of "Determining the number of male and female individuals in the database, displaying the count for each gender" using SQLite. Upon entering a query SELECT sex, COUNT(name) from employee_table GROUP BY sex ORDER BY sex DES ...

The attempt to access a Spring Boot webservice using AngularJS and the GET method resulted in a 500 status error, indicating that the operation

I have successfully developed a webservice using springboot and angularjs to download an excel file from the server to my local machine. The URL is being generated correctly, however, I am encountering a 500 error. Below is the code snippet: My Springboot ...

Utilizing ng-class with Boolean values in AngularJS

On my page, I have a pair of buttons that control the visibility of elements using ng-hide and ng-show. <a ng-click="showimage=true" ng-class="{ 'activated': showimage}" class="button">Images</a> <a ng-click="showimage=false" ng-c ...

Trigger an event from the main js file in Electron to communicate with a Vue component

I am currently developing an electron app powered by electron version 5.0.0 The issue I'm facing is with utilizing electron's power monitor feature, which can only be accessed from the main electron js file. However, I need to communicate this i ...

Unable to display data retrieved from JSON file

I am encountering an unusual issue while trying to retrieve elements from JSON in JavaScript. I fetch a JSON string from a URL using the following code: // Create Request HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"www.someurl ...

What is the process for organizing a table column with the use of a <select> tag?

My goal is to implement column sorting in a table. I've managed to sort the columns by clicking on the table header using jQuery (e.g., `$('th').click(function(){ )`, but I'm struggling to achieve the same functionality using select opt ...

Prevent the onClick event from being triggered by utilizing JSON data

I am trying to implement a feature where a button click is disabled based on a parameter fetched from a JSON file: JSON Parameter "reactJson": { "disable:"true" } Currently, my onClick method is functioning correctly. However, ...

How can you determine if a domain belongs to Shopify when given a list of 98000 domain names using Node.js?

Is there a way to determine if a domain is operating on the Shopify e-commerce platform? I have been searching extensively but haven't found a reliable method. I possess an array containing 98,000 domain names and I am interested in utilizing node.js ...

Tips for accessing the information received from an AJAX call

When making an AJAX post request for processed data from the database in the form of an array [value1, value2, value3,...,valueN], I aim to use it on a ChartJS object. Here is the AJAX Request: $(document).ready($.post('callMeForAJAX.jsp', func ...

Failed network request in my ReactJS project under the "Auth/network-request-failed" error code

I'm currently working on a project focused on learning to use react-router-dom and firebase authentication for user sign-in and sign-up. However, I've run into an issue where I keep getting a FirebaseError: "Firebase: Error (auth/network-request- ...

Closing tag in jQuery

In my script, I am using a div tag within the jquery code. However, whenever the div tag appears in the jquery code, it automatically closes the script tag and breaks the jquery code. For example, consider the following code: <script>var b = 25;var ...

PHP error: Trying to access an index that doesn't exist

Help! I encountered the following error Notice: Undefined offset: 1 in file.php on line 113 The problematic line of code is $publish_content=$matches2[1]; This is my code snippet if(!preg_match('/\<content\:encoded\> ...

Unable to remove files from Google Cloud Storage through Firebase Functions

After struggling for nearly a week, I am still unable to successfully delete files from my Firebase Storage using Firebase Functions. The closest I've come is encountering an error message within the error itself, saying "Cannot parse JSON response at ...

What are the steps to develop a progress bar using PHP and JavaScript?

In the application I'm developing, PHP and JavaScript are being used extensively. One of my tasks involves deleting entries from the database, which is a time-consuming process. To keep the end-user informed, I would like to provide updates on the pr ...

Encountering syntax errors in GraphQL

Currently, I am in the process of working on the GraphQL Node tutorial and have reached step 7. Visit this link to view Step 7 While implementing the code in my datamodel.prisma file, I encountered several syntax errors: directive @id on FIELD_DEFINITIO ...

ng-switch is failing to function in specific instances

I'm currently constructing a login module using AngularJS. Below is the code snippet: For the main page HTML: <div id='main' ng-controller='LoginController'> <div class='yomate-header'> <div c ...

The property 'matMenuTrigger' cannot be attached to 'a' because it is not recognized

Trying to implement matMenuTrigger but encountering an error saying "Can't bind to 'matMenuTrigger' since it isn't a known property of 'a'". Any assistance would be greatly appreciated. ...