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

Escaping back slashes in Node.js

I am currently encountering an issue with escaping backslashes. Below is the code snippet that I have attempted. The problem lies in how to assign a variable containing an escaped slash to another variable. var s = 'domain\\username'; ...

The webpage loaded through ajax is not rendering correctly

One of the challenges I'm facing is getting a JavaScript script to load an HTML page into a specific div element on another HTML page: The page that's being loaded, startScreen.html, looks like this: <!DOCTYPE html> <html lang="en ...

Assigning attributes to inner components in VueJS based on prop values

Experimenting with some common VueJS syntax, but I am struggling to get this Button.vue SFC to function properly: <script setup> defineProps({ ... href: String, ... }); </script> ... <template> <Link :href="href&quo ...

locate the following div using an accordion view

Progress: https://jsfiddle.net/zigzag/jstuq9ok/4/ There are various methods to achieve this, but one approach is by using a CSS class called sub to hide a 'nested' div and then using jQuery to toggle the Glyphicon while displaying the 'nest ...

The functionality of Bootstrap popover is not functioning properly

I'm trying to activate a popover when users hover their mouse over a div. Can I use a popover with a div, or am I missing something in my code? Here's what I have: <div class="grid-item content-text" data-toogle ="popover" data-content="Lorem ...

Avoid using fs.read without returning a value to console.log

Seeking assistance with parsing a text file named information.txt and displaying the values using console.log. Here is the code snippet: fs.readFileSync("information.txt", "utf-8", function (err, data) { ...

Show the React component once the typewriter effect animation is complete

Hello there, I am looking to showcase my social links once the Typewriter effect finishes typing out a sentence in TypeScript. As someone new to React, I'm not quite sure how to make it happen though. Take a look at the code snippet below: ` import ...

Tips on working with an array received from a PHP script through AJAX

I've been stuck with this issue for the past few hours and I'm hoping to find a solution here. What I'm attempting to do is something like the following: PHP: $errorIds = array(); if(error happens){ array_push($errorIds, $user['user ...

Creating a linear video playback system

Having an issue with my code in Chrome where auto play is enabled, but the video won't play. I have a loop set up to play each video one after the other, but first things first - how do I get this video to start playing? If there's a pre-made so ...

HTML not being able to execute Javascript when using an SSL connection

While serving HTML via Jenkins HTTPS with an invalid security certificate, the following code is included: <!DOCTYPE html> <html> <head> <script type="text/javascript">alert(1);</script> <script type="text/javascri ...

Necessitating derived classes to implement methods without making them publicly accessible

I am currently working with the following interface: import * as Bluebird from "bluebird"; import { Article } from '../../Domain/Article/Article'; export interface ITextParsingService { parsedArticle : Article; getText(uri : string) : B ...

A step-by-step guide on extracting nested ASP.NET DataGrid values with JavaScript

Looking to retrieve data from a nested data grid on an aspx page using JavaScript. Check out the following code snippet: <tr> <td colspan="2" align="center"> <asp:DataGrid ID="sampleData" AutoGenerateColumns="false" runat="serv ...

locomotory mesh decentralized sorting

I am attempting to implement in-browser sorting for my flexigrid. Currently, the grid is displaying data from a static XML file exactly how I want it, but the table itself does not sort because it is working off of local data. While researching solutions, ...

Guide to Re-rendering a component inside the +layout.svelte

Can you provide guidance on how to update a component in +layout.svelte whenever the userType changes? I would like to toggle between a login and logout state in my navbar, where the state is dependent on currentUserType. I have a store for currentUserTyp ...

The AJAX status is now 0, with a ready state of 4

Struggling to execute an AJAX call (using only JavaScript) to store a user in the database. The JavaScript file I am working with includes this code: var url = "interfata_db.php"; xmlhttp.onreadystatechange = function(){ alert('ready state &apos ...

Is there a way to transfer the jQuery code I've developed on jsfiddle to my website?

I am currently developing a website for fun, using HTML and CSS. While I have some familiarity with these languages, I have never worked with jQuery before. However, for one specific page on the site, I wanted to incorporate "linked sliders," which I disco ...

Leveraging the combination of <Form>, jQuery, Sequelize, and SQL for authentication and navigation tasks

My objective is to extract the values from the IDs #username-l and #pwd-l in an HTML form upon the user clicking the submit button. I aim to compare these values with those stored in a SQL database, and if they match exactly, redirect the user to a specifi ...

Exploring the process of retrieving outcomes from Node.js within a Knockout ObservableArray

Below is the Node.js code snippet I have: var http = require('http'); var port = process.env.port || 1337; var MovieDB = require('moviedb')('API KEY'); MovieDB.searchMovie({ query: 'Alien' }, function (err, res) { ...

Ensure that all MySQL queries within a for loop have completed before executing the rest of a function in NodeJS

I have been attempting to execute a query in order to retrieve data from one table, then utilize that array of data to fetch information from another table before formatting and returning it as JSON. Despite my efforts, I am struggling to understand how t ...

What is the process for executing mocha tests within a web browser?

Am I the only one who thinks that their documentation lacks proper instructions on running tests in the browser? Do I really need to create the HTML file they mention in the example? How can I ensure that it runs the specific test cases for my project? I ...