Currently, I’m designing IndexedDB functionality for my company. I have built a solid class and all of my unit tests work. However, when I’m attempting to open a new database for a client, the state of my Reducer never updates so the site hangs. I believe it is because the initDatabase
method is looking for a resolution to the Promise
. Here’s the Reducer I’ve built:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { DatabaseManager } from '../DatabaseManager';
// Async thunk to initialize the database
export const initializeDatabase = createAsyncThunk(
'database/initialize',
async (dbName, thunkAPI) => {
try {
const databaseManager = new DatabaseManager();
await databaseManager.initDatabase(dbName);
return databaseManager;
} catch (error) {
return thunkAPI.rejectWithValue(error.message);
}
}
);
const databaseSlice = createSlice({
name: 'database',
initialState: {
instance: null,
status: 'idle',
error: null,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(initializeDatabase.pending, (state) => {
state.status = 'loading';
})
.addCase(initializeDatabase.fulfilled, (state, action) => {
state.status = 'succeeded';
state.instance = action.payload;
})
.addCase(initializeDatabase.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message;
});
},
});
export default databaseSlice.reducer;
Here’s the initDatabase method:
async function initDatabase(dbName) {
// Validate dbName
if (!dbName || typeof dbName !== 'string' || !/^[a-zA-Z0-9]+$/.test(dbName)) {
throw new Error('Invalid dbName: Must be a non-empty alphanumeric string');
}
// Prevent reinitialization of db if already created
if (this._db) {
console.log(`Database ${this._db.name} is already initialized.`);
return this._db;
}
// Standardize name that will populate in browser
const request = window.indexedDB.open(dbName);
return new Promise((resolve, reject) => {
request.onsuccess = (event) => {
this._db = event.target.result;
resolve(this._db);
};
request.onerror = (event) => {
console.error(`Failed to initialize ${dbName}: ${event.target.errorCode}`);
reject(event.target.error);
};
});
}
What do I need to change to resolve the Promise
and get the action.payload
to the state
?