Ralph
Ralph

Reputation: 161

Transaction finds only 1st object store created after initializing IndexedDB with 2 object stores

I found several posts asking about if, and how, you can create multiple object stores in a single IndexedDB database. That is not really my issues I think. I have created 2 object stores in a single onupgradeneeded event and I see both stores in the developer console of Google Chrome. So I guess that works.

One object store stores workouts, the other exercises that refer to a workout by ID (I tried combining them in a single object store but that was too much hassle when updating info). When I try to retrieve a workout from the 1st object store and the corresponding exercises from the 2nd object store, the app cannot find the 2nd object store anymore. Only the 1st object store seems to be available.

The following code hopefully explains the issue better:

db.service.ts

Database initialization:

private db: IDBDatabase;

constructor() { }

public init(): Promise<void> {
    if(this.db) {
        this.db.close();
    }
    return new Promise(resolve => {
        const req = indexedDB.open('workoutsDB', 1);
        req.onupgradeneeded = e => {
            const db = (e.target as any).result;
            const workouts = db.createObjectStore(
                'workouts', {keyPath: 'id'});
            workouts.put({id: '1', name: '5x5'});
            const exercises = db.createObjectStore(
                'exercises', {keyPath: 'id'});
            exercises.put({id: '1', workout: '1', name: 'Squats'});
            exercises.put({id: '2', workout: '1', name: 'Bench presses'});
        }
        req.onsuccess = e => {
            this.db = (e.target as any).result;
            resolve();
        }
    });
}

Get a workout:

public getWorkout(id): Promise<Workout> {
    return new Promise<Workout>(resolve => {
        var tx = this.db.transaction('workoutsDB', 'readwrite');
        var store = tx.objectStore('workouts');  // <= THIS WORKS!!!
    });
}

Get exercises of a workout:

public getExercises(workoutId): Promise<Exercise[]> {
    return new Promise<Exercise[]>(resolve => {
        var tx = this.db.transaction('workoutsDB', 'readwrite');
        var store = tx.objectStore('exercises'); // <= ERROR!!!
    });
}

The functions getWorkout(id) and getExercises(workoutId) are called from a Ionic page as follows:

workout.page.ts

workout: Workout;
exercises: Exercises[] = [];

constructor(private db: DbService) { }

ngOnInit() {
    var id = this.route.snapshot.paramMap.get('id');
    this.db.init().then(() => getWorkout(id));
}

getWorkout(id) {
    this.db.getWorkout(id).then(workout => {
        this.workout = workout;
        this.db.getExercises(id).then(exercises => {
            this.exercises = exercises;
        });
    });
}

I'm not sure what I'm doing wrong. Obviously, getting the exercises requires that I FIRST retrieve the corresponding workout. I thought perhaps there's a conflict between different transactions or something but I cannot manage to pin-point the problem.

Any help would be greatly appreciated!

Upvotes: 0

Views: 90

Answers (1)

dumbmatter
dumbmatter

Reputation: 9683

The first argument to this.db.transaction is wrong. It should be an array of names of all the object stores you will use in the transaction (or, if it's just a single object store, it can be a string containing just that name). Instead you are putting the name of your database there. Most likely that is your error.

If not, please edit your post to include the specific error message you are seeing, that would make it easier for people to help you. Or include a minimal example we can run, to observe the error ourselves.

Upvotes: 2

Related Questions