IDB's Observable fails to produce any results

I am currently in the process of transforming the promises from the indexDB library 'idb' into Observables. While inserting values into the database is successful, I encounter an issue when initializing my service to retrieve values from the indexDB.

My goal is to ensure that the indexDB initialization is completed before calling the getTable functions. The initialization process is functioning as intended, but reading the values afterwards proves to be problematic.

private indexDB: IDBPDatabase<DatabaseSchemaV1>;
indexDB$ = new Subject<IDBPDatabase<DatabaseSchemaV1>>();

private initIndexDB$() {
        return from(
            openDB<DatabaseSchemaV1>(this.dbName, this.DB_VERSION, {
                upgrade(db) {
                    db.createObjectStore(IndexDBTable.TABLE1);
                    db.createObjectStore(IndexDBTable.TABLE2);
                },
            })
        ).pipe(
            map((indexDB) => {
                this.indexDB$.next(indexDB);
                this.indexDB = indexDB;
                return this.indexDB$;
            })
        );
    }


public getTableUserExercises$(): Observable<ExerciseTableItem[]> {
    if (!this.indexDB) {
        return of([]);
    }
    return from(
        this.indexDB
            .transaction(IndexDBTable.UserExercises)
            .objectStore(IndexDBTable.UserExercises)
            .getAll()
    );
}

public getTableTrainUnits$(): Observable<TrainUnit[]> {
    if (!this.indexDB) {
        return of([]);
    }
    return from(
        this.indexDB
            .transaction(IndexDBTable.TrainUnit)
            .objectStore(IndexDBTable.TrainUnit)
            .getAll()
    );
}

private getTables$() {
    return combineLatest([
        this.getTableUserExercises$().pipe(),
        this.getTableTrainUnits$().pipe(),
    ]);
}


constructor() {
        // this._indexDBSub = this.initIndexDB$()
        //  .pipe(map(() => this.getTables$()))
        //  .subscribe((values) =>
        //      console.log('In IndexDBSub after getTables: ', this.userExerciseTable)
        //  );

        // this._getTablesSub = this.getTables$()
        //  .pipe(
        //      map((values) => {
        //          console.log('Arrays in getTablesSub: ', values[0], values[1]);
        //      })
        //  )
        //  .subscribe((what) => console.log(what));

        const indexDB = this.initIndexDB$();
        const trainUnits = this.getTableTrainUnits$();
        indexDB.pipe(concat(trainUnits)).subscribe((x) => console.log(x));
    }

Within the constructor, I have experimented with concat, mapping, and combineLatest calls from RxJS, but unfortunately, none of them have resolved the issue. However, a single observable can be called successfully by manually waiting for the indexDB:

this.getTableUserExercises$()
            .subscribe((values) => console.log(values));

Answer №1

I am a bit puzzled by the example provided, as there is one aspect that seems unclear to me.

In this particular line

indexDB.pipe(concat(trainUnits)).subscribe((x) => console.log(x));

The use of the concat operator with a function that returns an Observable appears questionable. For cases like these, where you want to concatenate a series of Observables to be executed sequentially, it is recommended to use operators such as concatMap. This type of operator flattens the inner Observable and passes its value on to the next subscribe.

Therefore, the corrected code should look like this:

indexDB.pipe(concatMap(trainUnits)).subscribe((x) => console.log(x));

Other similar operators that flatten inner Observables include mergeMap (also known as flatMap), switchMap, and exhaustMap.

If you need more guidance on common rxJs use cases, you may find helpful insights in this article.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to Implement the Play/Pause Button in an Angular Application

I'm working on adding a show/hide feature to the play and pause buttons for a list of tracks in Angular 7. I had some success with Angular animation initially, but encountered an issue where all buttons in my list would change state instead of just on ...

Compiling Vue with TypeScript: Troubleshooting common errors

Using Vue Components with Templates Multiple Times in TypeScript I am working on utilizing a component with a template multiple times within another component. The code is split between a .html file and a .ts file. The .html file structure is as follows: ...

Functionality issues with Angular Material's Mat-select component

I am currently working with the latest version of Angular Material and I've encountered an issue with the mat-select component. Here is the snippet from my HTML: <mat-form-field> <mat-select placeholder="Favorite food" [(value)]="sel ...

"Delightful combination of Mocha, Typescript and the beauty of recursive loading

When using the following script: "test": "./node_modules/mocha/bin/mocha --recursive --require ts-node/register ./test/**/*.spec.ts --opts ./test/mocha.opts", I attempted to load test files from within the directory structure: . ├── controllers ...

Transform GraphQL data into a JSON format for easier processing

I have developed a JSON api that takes JSON input from Postman and converts it into a graphql request in order to communicate with an external endpoint that exclusively accepts graphql. The conversion process is successful as I am receiving valid graphql r ...

What is the best way to make TypeScript's Array.map() function return the same results as in VanillaJS?

For my Angular6 App project, I am currently working on implementing Conway's Game of Life. My goal is to create a two-dimensional array of class instances with dimensions n x m. In vanillaJS, I managed to achieve this using the following code snippet: ...

Display alternative navigation paths to the user in Angular that differ from the original routes

I am currently developing a full stack web application using Angular, Node (Express), and mySQL. I am looking to display a different route to the user than the actual one. Is there a way to achieve this? For instance, let's say this is my dashboard pa ...

Having trouble with Typescript accurately converting decimal numbers?

I am struggling with formatting decimals in my Typescript class. export myclass { deposit: number; } After converting my web API class to this Typescript class, my decimal amounts lose their additional zero. For example, 1.10 becomes 1.1. I want to keep ...

Tips for incorporating the closeAutocomplete function into ng4-geoautocomplete

Hey there! I've incorporated the ng4-autocomplete component into my custom component and now I'm trying to figure out how to detect when the autocomplete dropdown closes. Can you help me out with implementing the "closeAutocomplete" method? Let& ...

Solana Metaplex Maker Dispute Resolved

Currently experimenting with the Metaplex Storefront, I have incorporated 2 whitelisted wallets for my auction page through the admin section (one of which was used to initialize the page). I conducted a test auction with this particular NFT () that has 2 ...

arrange the css styles in angular

Currently working with Angular and looking to adjust the CSS specificity on the webpage displayed in the link below: https://i.sstatic.net/X3MHW.png The goal is to load 2 before 1. Any suggestions on how to achieve this? ...

Error: React is throwing a SyntaxError because a ")" is missing in the argument list

While working on a React-typescript project using Vite, I encountered an issue where my page was displaying blank and showing the error : Uncaught SyntaxError: missing ) after argument list (at main.tsx:6:51) This error was found in the main.tsx file : im ...

In TypeScript, the NonNullable type is like Required, but it ensures that all object properties are converted to non-

When working with TypeScript, you may have come across the Required type which transforms object properties into defined ones. For instance: interface Person { name?: string; age?: number; } Using Required<Person> will result in: interface Pe ...

Change the name of the interface from the imported type

When working with Google Apps Script, I have implemented the Advanced Calendar Service, originally labeled as "Calendar". However, I have renamed it to "CalendarService". How can I incorporate this name change when utilizing the type definitions for Apps S ...

Trigger an HttpException within a NestJS service

When it comes to handling errors in NestJS services, is throwing an Http Exception a recommended approach? What are some best practices for managing errors within a service in NestJS? ...

Understanding the Typescript Type for a JSON Schema Object

When working with JSON-schema objects in typescript, is there a specific type that should be associated with them? I currently have a method within my class that validates whether its members adhere to the dynamic json schema schema. This is how I am doing ...

Angular 4 navbar seamlessly integrated with Bootstrap 4

I have recently developed an Angular 4 application and I am looking to integrate Bootstrap 4 into it. After installing Bootstrap 4.0.0-beta6 via npm, I wanted to use the starter template which should resemble this design. https://i.sstatic.net/ANaBz.png ...

Determining the return value using Typescript inference with multiple subclasses of Error

My function is designed to return either a number, an Error, or a NegativeError: class NegativeError extends Error { name = 'NegativeError' } function doThing (a: number): number | NegativeError | Error { return a < 0 ? new NegativeError( ...

Sometimes, it feels like TypeScript's async await does not actually wait for the task to complete before moving on

Recently, I have been transitioning to using the async await pattern more frequently instead of the traditional Promise syntax because it can help in keeping the code structure cleaner. After some experimentation, I felt like I had a good grasp on how to u ...

Creating Excel documents using Angular and XLSX template generator

In my Angular application, I am utilizing the XLSX library to manipulate an Excel file. The file I start with is encoded in base64 format, so my first task is to decode it, make some changes to specific cells, and then save the modified file back in base64 ...