react-native-sqlite-storage icon indicating copy to clipboard operation
react-native-sqlite-storage copied to clipboard

Db.transaction does not wait for promise.all

Open uutkarshsingh opened this issue 10 months ago • 1 comments

I have the following code in a function

          return Database.createDatabase()
          .then((database)=> {
            return insertSurvey(parsedData,database)
          })
          .then((outa)=>{
            console.log(outa)
          })

The createDatabase enables sqlite promises The insertSurvey code is as follows

const insertSurvey =  (surveyObject : any, database) => {

  return database.transaction((tx) => {
    console.log("BEFORE SURVEY_INSERT_STRING executeSql")
    return tx.executeSql(
        Database.SURVEY_INSERT_STRING ,
        [
          surveyObject.troubleShooting,
        ]
       )
       .then(async ()=>{
        let arrayOfPromisesForAssetInsertion = []
        for(let count = 0 ; count < survey.assets.length; count ++)
        {
          arrayOfPromisesForAssetInsertion.push(insertAsset(tx,survey.assets[count], survey.surveyId))
        }
    
        return Promise.all(arrayOfPromisesForAssetInsertion)  // REACHED POINT
      })
      .then((valuesAfterAssetInsertion)=>{. 
        console.log(valuesAfterAssetInsertion)  // DOES NOT REACH HERE

        let arrayOfIssuesInsertion = survey.assets.map((asset) => 
          insertIssues(tx, asset, survey.surveyId)
        );
        return Promise.all(arrayOfIssuesInsertion)
      })
      .catch((msg)=>{
        console.log("error caught ",msg)
      })
  })
    .then((sur)=>{
      // console.log("returning transaction and surveyObject",tx,surveyObject)
      **return "output"**. // LINE OUTPUT
    })
  }




function insertAsset(tx, asset, surveyId) {
  setLoadingText ( "Assets")

  return tx.executeSql(
    Database.ASSETS_INSERT_STRING ,
    [
      asset.completed ?? false
    ])
  .then((values)=>{
      return values
  })
}


Here when the insertSurvey executes after reaching "return Promise.all(arrayOfPromisesForAssetInsertion)" the code jumps to "return "output" i.e // LINE OUTPUT. The following then statement is not reached The point // DOES NOT REACH HERE is not reached. There is no error as even catch is not reached. Why is the DB.transaction not hitting point "console.log(valuesAfterAssetInsertion)"

uutkarshsingh avatar Jan 26 '25 08:01 uutkarshsingh

I've been running into this a lot recently, and it's frustrating to debug. A few things that have helped me:

  • awaiting the secondary executeSqls instead of using their promises.
  • Wrapping the secondary executeSqls in a try/catch.

Usually, this results in the error:

InvalidStateError: DOM Exception 11: This transaction is already finalized. Transactions are committed after its success or failure handlers are called. If you are using a Promise to handle callbacks, be aware that implementations following the A+ standard adhere to run-to-completion semantics and so Promise resolution occurs on a subsequent tick and therefore after the transaction commits.

I will update you when/if I figure out a solution for running insert query inside a tx.executeSql callback.

ryanshepps avatar Jan 27 '25 18:01 ryanshepps