Appa
Appa

Reputation: 45

Neither Successcallback nor Errorcallback are being called after a transaction using Expo and an SQLite database

I tried to follow the examples on the Expo Docs about SQLite and also some more examples. Unfortunately I couldn't quite get it working. To debug I tried to add some callbacks and none of the callbacks were actually called. Neither success nor error callback.

This is my code for this small test:

import React, { useState, useEffect } from 'react';
import { Platform, ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View, Button, } from "react-native";
import * as SQLite from "expo-sqlite";

function App(props) {
  function openDatabase() {
    if (Platform.OS === "web") {
      return {
        transaction: () => {
          return {
            executeSql: () => {},
          };
        },
      };
    }
    const db = SQLite.openDatabase("db.db");
    return db;
  };
  
  const db = openDatabase();
  const [text, setText] = useState(null);
  const [forceUpdate, forceUpdateId] = useForceUpdate();

  useEffect(() => {
    console.log("Use Effect"); // this gets logged
    db.transaction((tx) => {
      tx.executeSql(
        "create table if not exists items (id integer primary key not null, done int, value text);",
        [],
        (_, res) => {console.log("Error initializing database!");},
        (_, err) => {console.log("Database was initialized");}
      );
    },
    [],
    (_, res) => {console.log("Error initializing database!");},
    (_, err) => {console.log("Database was initialized");});
  }, []);

  return (
    <View style={styles.container}>
      <Text>Test</Text>
    </View>
  );
}

function useForceUpdate() {
  const [value, setValue] = useState(0);
  return [() => setValue(value + 1), value];
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
});

export default App;

Maybe someone can point to what I did wrong. Thanks in advance.

Best, Fred

Upvotes: 1

Views: 238

Answers (1)

Kirill Novikov
Kirill Novikov

Reputation: 3067

There are a couple of steps to solve your problem.

  1. Init your database only once. Replace your implementation with:

const openDatabase = () => {
    if (Platform.OS === "web") {
      return {
        transaction: () => {
          return {
            executeSql: () => {},
          };
        },
      };
    }
    const db = SQLite.openDatabase("db.db");
    return db;
};

function App(props) {
  const [db, setDB] = useState(null);
  ...
  useEffect(() => {
    if (!db) {
      const instance = openDatabase();
      setDB(db)
    }
  }, [])

  useEffect(() => {
    if (db) {
      // do your transactions
    }
  }, [db])
}
  1. Remove forceUpdate

Upvotes: 1

Related Questions