Search code examples
javascriptreactjsreact-nativesqliteandroid-sqlite

EXPO SQLite, ReferenceError: Property 'db' doesn't exist, js engine: hermes


I am trying to open a database called expenses.db but I am getting the error,

ReferenceError: Property 'db' doesn't exist, js engine: hermes

This is the code I have written,

import { View, Text, Pressable, StyleSheet, StatusBar } from "react-native";
import Input from "../../src/components/input";
import { useState } from "react";
import { Picker } from "@react-native-picker/picker";
import * as SQLite from 'expo-sqlite';


const db = SQLite.openDatabase({
  name: 'expenses.db',
  location: 'default',
});

try {
  db.transaction((tx) => {
    tx.executeSql(
      'CREATE TABLE IF NOT EXISTS expenses (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, amount REAL, category TEXT)',
      [],
      () => {
        console.log('Table created successfully.');
      },
      (error) => {
        console.log('Error creating table:', error);
      }
    );
  });
}
catch (error) {
  console.log('Error executing SQL statement:', error);
}

const AddExpense = () => {
  const [Category, setCategory] = useState("food");
  const [Name, setName] = useState("");
  const [Amount, setAmount] = useState("");

  // Function to be executed once we get input from the user about the expense/Inserting an expense record
  const Add = () => {
    console.log("Input 1:", Name);
    console.log("Input 2:", Amount);
    console.log("Input 3", Category);

    db.transaction(tx => {
      tx.executeSql(
        'INSERT INTO expenses (Name, Amount, Category) VALUES (?, ?, ?)',
        [Name, Amount, Category],
        (_, { rowsAffected, insertId }) => {
          if (rowsAffected > 0) {
            console.log("Expense record inserted with ID:", {insertId});
          }
        },
        (_, error) => {
          console.log("Error inserting expense record:", error);
        }
      );
    });
  };

  return (
    <View style={styles.container}>
      <Text>GastoCalc</Text>

      <Input
        text={"Name Of Expense"}
        placeholder={"What did you spend on?"}
        multiline={false}
        value={Name}
        onChangeText={(text) => setName(text)}
      />
      <Input
        text={"Expense Amount"}
        placeholder={"₹ ??"}
        inputMode={"numeric"}
        value={Amount}
        onChangeText={(text) => setAmount(text)}
      />

      <View style={styles.inputContainer}>
        <Text style={styles.inputText}>Category Of Expense</Text>

        <View style={styles.inputBorder}>
          <Picker
            // Updating category mutable variable everytime a new option is selected
            selectedValue={Category}
            onValueChange={(itemValue, itemIndex) => setCategory(itemValue)}
            style={styles.input}
          >
            <Picker.Item label="Food" value="food" />
            <Picker.Item label="Rent" value="rent" />
            <Picker.Item label="Fuel" value="fuel" />
            <Picker.Item label="Miscellaneous" value="mics" />
          </Picker>
        </View>
      </View>

      <View style={styles.buttonView}>
        <Pressable style={styles.addButton} onPress={Add}>
          <Text>ADD</Text>
        </Pressable>
      </View>
    </View>
  );
};

export default AddExpense;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: StatusBar.currentHeight,
  },
  addButton: {
    backgroundColor: "lightgreen",
    alignItems: "center",
    justifyContent: "center",
    width: 75,
    height: 30,
  },
  buttonView: {
    flex: 1,
    justifyContent: "flex-end",
    alignItems: "center",
    marginBottom: 30,
  },

  // Styles for picker tag which will eventually be transferred to a different file.
  input: {
    marginTop: -9,
  },
  inputText: {
    fontSize: 15,
    alignItems: "baseline",
  },
  inputContainer: {
    flexDirection: "column",
    alignItems: "center",
    marginLeft: 15,
  },
  inputBorder: {
    borderWidth: 1,
    height: 40,
    width: 240,
    marginTop: 10,
  },
});

The error is particularly in the area below, I found this out using a try and catch block which I have removed since then,

const db = SQLite.openDatabase({
  name: 'expenses.db',
  location: 'default',
});

I am not sure where the problem is and there is no information about this on the internet as well. Any help is appreciated.


Solution

  • According to the documentation(https://docs.expo.dev/versions/latest/sdk/sqlite/), I was using the wrong arguments for the openDatabase function.

    I instead needed to write the below code to open a connection to the database,

    const db = SQLite.openDatabase(expenses.db);