Having trouble with creating SQLite tables using JavaScript within a for loop

I have developed a multi-platform app using AngularJS, JavaScript, Phonegap/Cordova, Monaca, and Onsen UI.

In order to enable offline usage of the app, I have integrated an SQLite Database to store various data. After conducting some basic tests, I confirmed that this functionality is working correctly.

My current challenge involves creating all 28 required tables within my app's initial view function onDeviceReady(). To achieve this, I am iterating through an array of objects and executing the SQLite CREATE statement for each table.

Defining table values

// Form values
var formValues = [{
    tablename: "table_1",
    id: "id_1",
    desc: "desc_1",
    dataType: "TEXT"
}, {
    tablename: "table_2",
    id: "id_2",
    desc: "desc_2",
    dataType: "TEXT"
}, {
    ...
    ...
    ...
    ...
}, {
    tablename: "table_28",
    id: "id_28",
    desc: "desc_28",
    dataType: "TEXT"
}];

Creating the tables

function onDeviceReady() {
    for (var i = 0; i < formValues.length; i++) {
        var createFormValues = 'CREATE TABLE IF NOT EXISTS ' + formValues[i].tablename + ' (' + formValues[i].id + ' INTEGER, ' + formValues[i].desc + ' ' + formValues[i].dataType + ')';
        alert("SQL: " + createFormValues +
            "\n\nForm: " + formValues +
            "\nName: " + formValues[i].tablename +
            "\nID: " + formValues[i].id +
            "\nDesc: " + formValues[i].desc +
            "\nType: " + formValues[i].dataType);

        db.transaction(function (tx) { tx.executeSql(createFormValues); });
    }
};

After running the code above, I found that only the last table was created when querying the tables post loop execution.

To address this issue, I resorted to calling individual functions for each table creation, which proved to be less efficient but successful in generating all tables.

Calling a function

createFormTables("table_1", "id_1", "desc_1", "TEXT");
createFormTables("table_2", "id_2", "desc_2", "TEXT");
createFormTables("...", "...", "...", "...");
createFormTables("table_28", "id_28", "desc_28", "TEXT");

Executing the function

createFormTables: function (tableName, id, description, dataType) {
    var sql = 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + id + ' INTEGER, ' + description + ' ' + dataType + ')';
    alert("Create Form Field SQL: " + sql);
    db.transaction(function (tx) { tx.executeSql(sql); });
},

The asynchronous nature of SQLite statements seems to be causing the discrepancy between the two approaches. I am unsure why the first method fails to create all tables while the second one succeeds. How can I ensure that the tables are created using the initial approach without resorting to delays?

Answer №1

When calling the function 'createFormTables', I prefer using the JavaScript "Object" approach to prevent conflicts. Here's an example:

var QuerySet = function(){
    this.defRes = new $.Deferred();
    this.defResProm = this.defRes.promise();
};

QuerySet.prototype.createFormTables= function(inputData){
      // Handle your tasks here and resolve this.defRes once finished
     this.sqlToExecute = "// YOUR SQL QUERY"; 
     var self=this;
    $.when(
        (new SqlResult(this.sqlToExecute)).execSqlCustomDeferred(),
        self
    ).done(function(sqlRes,self){
        self.defRes.resolve();
    });

      return this.defResProm;
};

In your code, you can do:

createFromTables[i] = (new QuerySet()).createFormTables(inputData);
createFromTables[i].defRes.done(function(res){//do stuff with the result});

Using $.Deferred() may not be necessary, but it can be useful if you need to track when all tables are created.

The following is sqlResult, used for DB transactions:

var SqlResult = function(sqlToExecute, bracketValues){
    this.sqlToExecute = sqlToExecute;
    this.bracketValues = bracketValues;
};

SqlResult.prototype.execSqlCustomDeferred = function(){
    var execSqlCustomDeferredRes = $.Deferred();
    var execSqlCustomDeferredResProm = execSqlCustomDeferredRes.promise();  

    var sqlToExecuteForTx = this.sqlToExecute;
    var bracketValuesForTx = this.bracketValues;

    DbManagement.db.transaction(function(tx){
        console.log("Executing in transaction: "+sqlToExecuteForTx);

        if(bracketValuesForTx != null){
            console.log("Bracket values: "+ArrayManagement.arrayToString(bracketValuesForTx));
        }
        
        tx.executeSql(sqlToExecuteForTx,bracketValuesForTx,success,error);
        
        function success(tx,rs){
            execSqlCustomDeferredRes.resolve(rs);
        }

        function error(tx,error){
            console.log('Error during execution: '+error.message);
            execSqlCustomDeferredRes.reject(error);
        }

    });

    return execSqlCustomDeferredResProm;
};

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

Replace specific text with a span element around it?

I am working with the following HTML code: <p class="get">This is some content.</p>. My goal is to modify it so that it looks like this: <p class="get">This is <span>some</span> content.</p>. To achieve this, I have ...

I want to use the enter key for posting, but also have the ability to use the shift and enter key to create a

$("#post_text").keydown(function(e){ // Checking if Enter key was pressed without shift key if (e.keyCode == 13) { // Prevent default behavior e.preventDefault(); } if (e.keyCode == 13 && !e.shiftKey) { alert('test'); } }); I a ...

When entering a sub-URL into the browser address bar, the routes do not display as expected

I am encountering an issue with navigating to different routes within my React application. While the home route is visible and functions properly when I start the app locally (npm run dev), I am unable to access other routes. No errors are displayed in t ...

Swap out the %20, which signifies a space in the iron router context

I am attempting to substitute the %20, which signifies a space in the URL, with a different character. Router.map(function () { this.route('promos', { path: '/:promo_name', waitOn: function(){ return Meteor.subscribe( ...

javascript issue with fetching data from URL using the GET method

Here is my attempt to fetch a JSON file from a server using asynchronous JavaScript promises. I am experiencing an issue where the result is undefined when using a specific URL, but it works when I use a different URL. Below is the working code with a dif ...

Modify meta titles according to specific url #id

My website is built in static HTML and our server does not support PHP or C#. Can JavaScript, jQuery, Ajax, or other technologies achieve the following: If the URL is: Https://example.com/page, the meta title will display as "home page". Https://example ...

Javascript and Codeigniter interaction: Using conditionals with Ajax

I am having trouble understanding this code snippet. I am currently studying Ajax and came across this piece of code that automatically inserts data. However, I am unsure about the line if(result=='12') then trigger ajax. What does the number 12 ...

How can custom JavaScript objects have tags set upon click?

When it comes to JavaScript object referring, things can get a bit confusing. Imagine having a tag like this: <button id='myButton'>Hello</button> Now, let's say you create a custom class in JavaScript: function myClass(){ ...

Switching up the content of an HTML page with JavaScript or JQuery: what you need

Is it possible to update HTML content using JavaScript or JQuery? I am trying to change the contents from 1 to 5 in a sequential order based on the time shown in the image. How can I achieve this using JavaScript or JQuery? Any suggestions for search keyw ...

JavaScript is reliant on the presence of the alert() function to properly function

I have a JavaScript function that performs well, except for when I remove or comment out the alert() line. This function is designed to calculate the sum of values in up to 30 fields if they are present and contain a value. Here is an example of the HTML ...

Issue encountered while attempting to write KML objects to Google Earth API: NPObject error

Currently, I am working on a script that aims to extract data from Facebook and display it graphically on a Google Map using simple extruded polygons. The social integration and AJAX functionality are both working fine for me. However, whenever I try to ex ...

Are there specific mathematical algorithms that lend themselves well to creating responsive HTML designs?

Tired of constantly guessing the percentage values to use with a specific number of divs and other elements in my design. I am looking to understand the mathematical calculations that determine the scaling required for different elements in order to main ...

What is the best way to activate a JQ function with my submit button?

Is there a way to trigger a JQ function when clicking the submit button in a form? I managed to make Dreamweaver initiate an entire JS file, but not a particular function. ...

Display information based on the radio button chosen

I've set up a radio button with options for "no" and "yes", but neither is selected by default. Here's what I'm trying to achieve: If someone selects "no", nothing should happen. However, if they select "yes", then a message saying "hello w ...

Contrasting onevent with addEventListener

After studying various DOM events, I attempted to implement the 'blur' event on the HTML body. My first attempt was with onblur document.body.onblur = () => { dosomething(); } and I also tried using AddEventListener document.body.addEven ...

suggestions for customizing Angular Material

The guidelines regarding materials specify that: "For any Angular Material component, you are allowed to define custom CSS for the component's host element that impacts its positioning or layout, such as margin, position, top, left, transform, and z- ...

The output of new Date() varies between app.js and ejs

app.get("/test",function(req,res){ var d = new Date(); res.send(d); }); When I access mydomain/test, it displays the output "2019-03-19T04:50:47.710Z" which is in UTC. app.get("/testejs",function(req,res){ res.render("testejs");}); Below is the content ...

Displaying information on a chartJS by connecting to an API using axios in VueJS

Struggling with inputting data into a ChartJS line-chart instance. The chart only displays one point with the right data but an incorrect label (named 'label'): Check out the plot image The odd thing is, the extracted arrays appear to be accura ...

Which file from Next.js should I statically serve using Node?

Whenever I work with React, my standard process includes running npm build, moving the content to a directory named public in Node, and then including the following code snippets: node/app.js app.use(express.static(path.join(__dirname, 'public') ...

Check to see if the event handler is triggered and the promises are executed in sequence (syncronously)

I have a Vue button click handler that, depending on the arguments it receives, can do the following: execute request A only execute request B only execute request A and then request B sequentially (request B is only called if request A completes successf ...