Search code examples
node.jsrxdb

How to make this global variable hold its value between calls?


I'm trying to reduce the amount of times the database object is initialized in my data access file (variable database inside the file tree-rxdb.mjs). I created a global variable to hold a reference to the database object and check if it has been initialized before, if it has I just return the variable to the caller without initializing it again. For some reason, the database it's always undefined every time I call this function, even after I have successfully written to the database using the same code. Weirdly, the same doesn't happen to the dao variable inside tree.mjs even though I believe I'm giving it the same treatment but obviously getting differing results. I'm just emulating this code but for some reason it's not working out for the database variable inside tree-rxdb.mjs, what am I not seeing?

tree-rxdb.mjs

import RxDB from 'rxdb';
import adapter from 'pouchdb-adapter-leveldb'
import leveldown from 'leveldown'
import Log from '../utils/log.mjs';
const TAG = 'fruits-rxdb'

RxDB.plugin(adapter)

var database;

const treeSchema = {
    title: 'fruits schema',
    description: 'Describes a fruits tree',
    version: 0,
    type: 'object',
    properties: {
        name: { type: 'string' },
        desc: { type: 'string' },
        url: { type: 'string' },
        state: { 
            type: 'integer',
            enum: [0, 1]
        },
        favorite: {
            type: 'boolean'
        },
        dateAdded: { type: 'string' },
        userId: { type: 'string' }
    }
}

async function connectDB() {
    Log.debug(`Database object = ${database}`, TAG)
    if (database) return database;
    database = await RxDB.create({
        name: 'fruitsdb',
        adapter: leveldown,
        password: (process.env.DB_PASSWORD || 'myfruitsJsPasswordTemp')
    });
    await database.collection({
        name: 'trees',
        schema: treeSchema
    });
    Log.debug('Database has been initialized', TAG)
    return database;
}

export async function create(tree) {
    const db = await connectDB();
    db.trees.insert(tree.JSON);
}

tree.mjs

import util from 'util'
import logger from '../utils/log.mjs'
import Fruit from './Fruit.mjs'
const TAG = "tree-dao"

var dao;

async function model() {
    logger.debug(`DAO object = ${util.inspect(dao)}`, TAG)
    if(dao) return dao;
    dao = await import(`../dao/tree-${process.env.MODEL}`);
    logger.debug(`DAO model has been initialized: ${util.inspect(dao)}`, TAG);
    return dao;
}

export async function add(){
    const Fruit = new Fruit(undefined, 'Peach', 'peach 123',
        'http://something.com', 0, false, new Date().toISOString(), 'admin');
    (await model()).create(Fruit);
}

app.mjs

import express from 'express';
import logger from 'morgan'; 
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';
import { default as fruits } from "./routes/fruits"
import * as tree from './models/tree.mjs'

const app = express();

app.use(logger("dev"));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use("/fruits", fruits);

const add = async () => {
    await tree.add();
    await tree.add();
    await tree.add();
};
add();

export default app


Solution

  • I was missing an await in tree.mjs. The line (await model()).create(Fruit); should be await (await model()).create(Fruit); the inner await was throwing me off. Now it's behaving like I expected it to.