Reputation: 297
I am trying to make stores which can be accessed by Screens. File structure:
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
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
Reputation: 11
just add this lines
import {enablePromise, openDatabase } from 'react-native-sqlite-storage';
enablePromise(true)
Upvotes: 0
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 rundb.transaction()
directly.
Upvotes: 1
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
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