DASH
DASH

Reputation: 297

How to async await until I receive from database?

I am trying to make stores which can be accessed by Screens. File structure:

  1. index.ios.js
  2. /app/index.js
  3. /app/store/database.js
  4. /app/store/userStore.js

index.ios.js :

import { AppRegistry } from 'react-native';
import App from './app/index';
AppRegistry.registerComponent('AwesomeProject', () => App);

/app/index.js :

import React, { Component} from 'react';
import {
  Text,
  View,
} from 'react-native';
import userStore from './store/userStore';
import ViewBackground from './components/ViewBackground';

class App extends Component {
        constructor(props){
            super(props);
            this.isLoggedIn = true;     
        }

        componentDidMount() {       
            this.fetchUsers().done();
        }

        async fetchUsers(){
            console.log('Before User Fetch');
            var result = await userStore.getAllUsers();
            console.log('After User Fetch');
        }

        render() {
            if(this.isLoggedIn){
                return this.loggedInView();
            }else{
                return this.loggedOutView();
            }
        }

        loggedInView(){
            return <ViewBackground>

            </ViewBackground>
        }

        loggedOutView(){
            return <View>
            <Text>Hi, This is logged Out view </Text>
            </View>
        }
    }

    export default App;

/app/store/userStore.js :

import React from 'react';
    import database from './database';

    class UserStore{

        async getAllUsers(){
            let query = {
                type: 'SELECT',
                sql: 'SELECT * FROM Users',
                vals: [],
            }
            let queries = [query];
            console.log('in store before');
            let dbResult = await database.runQuery(queries);        
            console.log('in store after');
            return dbResult;        
        }
    }

    const userStore = new UserStore;

    export default userStore;

/app/store/database.js :

    'use strict';
    import React from 'react';
    import SQLite from 'react-native-sqlite-storage';
    SQLite.enablePromise(true);

    var database_name = "test.db";
    var database_version = "1.0";
    var database_displayname = "Test";
    var database_size = 1024 * 1024 * 10;

    class Database  {

        constructor(){
            SQLite.openDatabase(database_name, database_version, database_displayname, database_size).then(this.dbOpenSuccess).catch(this.dbOpenError);
        }

        dbOpenSuccess(dbInstance){
            this.conn = dbInstance;
        }

        dbOpenError(err) {

        }

        getConnection() {
            return this.conn;
        }

        setUpDatabase(){
            let queries = [
            'CREATE TABLE IF NOT EXISTS Users (user_id INTEGER PRIMARY KEY, f_name VARCHAR(64), l_name VARCHAR(64), email_id VARCHAR(128), mobile VARCHAR(10))'
            ];
            this.conn.transaction( tx => {
                queries.map( q => {
                    tx.executeSql(q, [], res => {}, err => {});
                });
            });
        }

        async runQuery(queries) {
            await this.conn.transaction(tx => {
                return Promise.all(queries.map(async (q) => {
                    try {
                        let results = null;
                        switch(q.type){
                            case 'SELECT':                      
                            results = await tx.executeSql(q.sql, q.vals);
                            console.log('Query', q, 'Executed. results:', results);
                            break;
                        }
                        
                    } catch(err) {
                        console.log('Something went wrong while executing query', q, 'error is', err);
                    }
                }));
            });
            return false;
        }

        closeDatabase(){
            this.conn.close().then(this.dbCloseSuccess).catch(this.dbCloseError);
        }

        dbCloseSuccess(res) {

        }

        dbCloseError(err){

        }
    }

    const dbInstance = new Database();

    dbInstance.setUpDatabase();

    export default dbInstance;

In /app/index.js I am trying to fetch users from userStore.js which will call database.js to retrieve the users from database. I want to pause execution when I fetch users from database, so tried async/await. I used console.log() to check whether execution paused. None of async/await is working. I am getting response after all console.log is done.

I want it to wait until I receive data from database.

Upvotes: 8

Views: 9794

Answers (5)

akshayitzme
akshayitzme

Reputation: 1

I follow this way to do DB operations

export const fetchUsers = async () => {
  return new Promise((resolve, reject) => {
    db.transaction(txn => {
      txn.executeSql('SELECT * FROM "Users";', [], (tx, res) => (
        resolve(res.rows.raw())
      ))
    })
  })
}

rows.raw() will return the data as object

(async()=>{
  data= await fetchUsers()
})()

Upvotes: 0

Mahendra Gohil
Mahendra Gohil

Reputation: 11

just add this lines

import {enablePromise, openDatabase  } from 'react-native-sqlite-storage';
enablePromise(true)

Upvotes: 0

roshnet
roshnet

Reputation: 2073

The following worked for me:

import { openDatabase } from 'react-native-sqlite-storage'

const db = openDatabase({
  name: 'app.db',
  location: 'default',
})

export default function App() {
  useEffect(() => {
    db.then((db) => {
      db.transaction((tx) => {
        tx.executeSql('SELECT this from that', [])
    })
  })
  /* Rest of the component... */
}

openDatabase returns a Promise, on resolving which we get the actual db on which we can run db.transaction().

You could use the async/await syntax too, but that would be a lot of encapsulation, and so .then() is always cleaner.

This is different from the "expo-sqlite" package, because db = openDatabase('app.db') does not return a Promise there. Instead, you can run db.transaction() directly.

Upvotes: 1

Danilo Santos
Danilo Santos

Reputation: 452

let  SQLite = require('react-native-sqlite-storage');
const  DB = SQLite.openDatabase({name:'test.db',createFromLocation:'~sqlitedb.db'});

class Database{
    db;
    constructor(db){
        this.db =db;
    }
    executeSql = (sql,params=[])=>new Promise((resolve , reject)=>{
        this.db.transaction((trans)=>{
            trans.executeSql(sql,params,(db,results)=>{

                resolve(results);
            },
            (error)=>{
                reject(error);
            });
        });
    });

}
export default  (new Database(DB));

use

 import Database from 'database';

 try
 {
   results = await DB.excuteSql("SQL",['params']);
 }
 catch(e)
 {

 }

Upvotes: 3

DMoon Huang
DMoon Huang

Reputation: 236

You need to wrap it in a Promise, then resolve the result when sql execution is done.

for example

async () => {
  return new Promise((resolve, reject) => {
    db.transaction(tx => {
      tx.executeSql('SELECT * FROM users;', [], (tx, results) => {
        const { rows } = results;
        let users = [];

        for (let i = 0; i < rows.length; i++) {
          users.push({
            ...rows.item(i),
          });
        }

        resolve(users);

      });
    });
  });

}

Upvotes: 10

Related Questions