0

I have thoroughly read through google and these 2 previous questions on stack overflow but as a noob Im still not getting the result i expect

How do I return the response from an asynchronous call?

How do I convert an existing callback API to promises?

In particular, one answer above says

"ES2017+: Promises with async/await

The ECMAScript version released in 2017 introduced syntax-level support for asynchronous functions. With the help of async and await, you can write asynchronous in a "synchronous style". The code is still asynchronous, but it's easier to read/understand."

...so that is the direction I have gone, using async/await

I have a button on a react native page that runs this code

onPressRefreshButton = async () => {
        const rows = await ReturnAllRowsFromTable('NameOfTable')
        console.log(rows)
    }

This function is in an imported file external to the above, it returns a list of all the rows in the table

export async function ReturnAllRowsFromTable(tableName){
    db.transaction(tx => {
        tx.executeSql(
            'SELECT * FROM ' + tableName + ';',
            [],
            (tx, results) => {
                if (results && results.rows && results.rows._array) {
                    console.log('all rows returned')
                    console.log(results.rows.item(0))
                    return await results.rows._array
                }
            },
            (tx, error) => {
                console.log(error);
            }
        )
    });
}

When I press the button I get the following in the console

undefined
all rows returned
Object {
  "key": "value",
  "key2": "value",
}

So it appears as if the console.log(rows) line is executing before the const rows = await ReturnAllRowsFromTable('NameOfTable') line even though I have async/await calls all through each function.

What have I done wrong?

zoonosis
  • 799
  • 1
  • 11
  • 30
  • 1
    `ReturnAllRowsFromTable()` isn't returning anything. – Mark Apr 05 '19 at 23:19
  • 1
    `ReturnAllRowsFromTable()` has no `return`. returning from an inner callback does not return to the outer function and the `executeSql` callback is not `async` – charlietfl Apr 05 '19 at 23:19

1 Answers1

2

You didn't return the result of the transaction, based on the provided API, you would create a new Promise to wrap the transaction operation and return it so that you can await its result:

export async function ReturnAllRowsFromTable(tableName){
    return new Promise(function(resolve, reject) {
        db.transaction(tx => {
            tx.executeSql(
                'SELECT * FROM ' + tableName + ';',
                [],
                (tx, results) => {
                    if (results && results.rows && results.rows._array) {
                        console.log('all rows returned')
                        console.log(results.rows.item(0))
                        resolve(results.rows._array); // return result to caller
                    }
                },
                (tx, error) => {
                    console.log(error);
                    reject(error); // return error to caller
                }
            )
        });
    });
}
Jack
  • 5,354
  • 2
  • 29
  • 54
  • 1
    Nothing returned to db.transaction and it may or may not be promise. doesn't look like promise – charlietfl Apr 05 '19 at 23:22
  • I'm talking about returning the result of the transaction – Jack Apr 05 '19 at 23:23
  • 1
    And inner await is not in async function – charlietfl Apr 05 '19 at 23:24
  • you are right about the await, I fixed it (though I'm not sure if that's how it would work), but the general idea would be to return it like what I did right? Also this transaction does look like a promise to me, that's why I answered this way. – Jack Apr 05 '19 at 23:29
  • Huh...wouldn't be using callbacks if it was promise. Without knowing that db api...can't just guess or assume. As it stands right now would be best to return a new Promise and resolve it inside the execute callback. Also the inner await is still invalid – charlietfl Apr 05 '19 at 23:31
  • For reference the db API is sqlite from expo , which is based on the one from Cordova – zoonosis Apr 05 '19 at 23:36
  • does it return a promise or anything that can use await on? – Jack Apr 05 '19 at 23:37
  • Here is a link to the api https://docs.expo.io/versions/latest/sdk/sqlite/ It doesnt mention anything about promises in the documentation – zoonosis Apr 05 '19 at 23:41
  • 1
    So it is a callback and that probably means the logic has to be implemented differently than what I did now – Jack Apr 05 '19 at 23:46
  • 1
    I have updated the answer which returns a new promise and hopefully you can use await with it now – Jack Apr 05 '19 at 23:52
  • Thanks to all who helped with this, ive learned a lot. The "returns a new promise" way of doing things has worked. – zoonosis Apr 06 '19 at 00:29