ReactiveX: Continuous flow of modal dialogs

My challenge is to display multiple bootstrap popups sequentially to the user, each containing a stream of messages. However, if I simply subscribe and show the messages one after the other, it might not wait for the user to dismiss a popup before showing the next one. This would lead to either repeatedly calling show('modal') or displaying only the last message.

One unconventional solution could be to introduce a delay between notifications using the debounce operator and hope that the user's response time aligns with this delay.

Another idea I've been pondering is creating a notification stream with a callback function at the receiving end to indicate when a notification has been handled.

export class CallbackNotification<T>  {
  parameter : T;
  callbackFunction: () => any;
}

export function notifyAndMoveNext<T>(source: Observable<T>)  : Observable<CallbackNotification<T>>  {
  let notifications = new BehaviorSubject<any>(0);
  return zip(source, notifications)
   .pipe(map(([a, n]) => <CallbackNotification<T>> { 
               parameter = a, 
               callbackFunction = () => notifications.next(0) 
     }));
}

Then, the implementation would look like:

notifyAndMoveNext(myMessagesObservable).subscribe(x => { this.currentNotification = x.callbackFunction; showModal(x.parameter); });

and in the button event handler of each popup

this.currentNotification();

This approach may not be suitable for shared subscriptions (publish and refCount). Are there any potential issues with this method that I might have overlooked? Any suggestions for alternative approaches?

Answer №1

To effectively handle notification messages, you can transform each message into an Observable or Promise that remains active until the user interacts with it. By utilizing concatMap, you can ensure that each notification is displayed only after the previous one has been dealt with.

Consider the following implementation:

const displayNotification = (notification) => {
    // Create a "cold" observable using RxJS defer function
    // This ensures the notification is shown when subscribed to
    return defer(() => new Promise(resolve => {
        // Set up currentNotification to resolve promise
        this.currentNotification = resolve;
        showPopUp(notification);
    }));
};

notifications.pipe(concatMap(displayNotification)).subscribe();

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

The issue arises when TypeScript declarations contain conflicting variables across multiple dependencies

My current project uses .NET Core and ReactJS. Recently, I updated some packages to incorporate a new component in a .tsx file. Specifically, the version of @material-ui/core was updated from "@material-ui/core": "^3.0.3" to "@material-ui/core": "^4.1.3" i ...

The HTML button triggers a function to execute on a different webpage when clicked

I'm facing a straightforward issue that I can't seem to figure out due to my limited experience with Angular and web development. The problem revolves around two components, namely home and dashboard. In the home.component.html file, there's ...

What exactly does the statement if(item.some((item) => !item.available) represent in typescript?

Can you explain the meaning of if(item.some((item) => !item.available))? While looking at some code randomly, I came across this snippet: if(item.some((item) => !item.available){ } I'm curious about what it signifies. Can you elaborate on it? ...

An interface designed for enums containing nested types

My task involves creating an interface for the state using an enum as a key and object as a value. How can I designate the enum as the key type? export enum Language { CS, EN } const [userInput, setUserInput] = useState<IUserInput>({ [Lan ...

The error message "The function 'combineLatest' is not found on the Observable type"

Hey there! I'm currently working on implementing an InstantSearch function into my website using Angular 12.2. To accomplish this, I'll be working with a Firestore database with the index "book-data". In my search component, I have included the f ...

Determining the typing of a function based on a specific type condition

I have created a unique type structure as shown below: type Criteria = 'Criterion A' | 'Criterion B'; type NoCriteria = 'NO CRITERIA'; type Props = { label?: string; required?: boolean; disabled?: boolean; } & ( | ...

What is the process for updating an observable value once another observable has been modified?

Is it possible to utilize a one-time subscription to an HTTP action inside an Angular service? Are there any drawbacks to this approach? public async signInAsync(userName: string, password: string): Promise<void> { try { const token = awai ...

Is there a way to customize the "instanceof" functionality for an ArrayBuffer?

I've been working on a project that involves using threejs to draw a filled polygon based on its vertices. Initially, I started with a square and was able to get it working perfectly on its own. However, the real issue arose when I tried to integrate ...

Using Required and Partial with an Array of Generic Types

I'm currently working with the following types: interface Color { color: string } type DarkerColor<T> = T & Color & { darker: string } type ColorInfo<T> = DarkerColor<T> & { hue: number luminance: number opacity ...

Using Cypress and JWT, automate the login process for JHipster

Is there a way to automate the bypassing of the JHipster login screen? This is my goal: let jwt_token before(function fetchUser() { cy.request('POST', '/api/authenticate', { username: 'user', password: &a ...

What is the procedure for setting up the typings folder in AngularJS 1.5 with TypeScript?

I'm currently working on a project using AngularJS 1.5 and TypeScript. I need to install the "angularjs/angular.d.ts" and "angularjs/angular-route.d.ts" files. Despite installing tsd globally, when I run the command "tsd install angular," I receive a ...

Is it Control or ControlGroup in Angular 2 - How to tell the difference?

let aa = this._formBuilder.control(""); let bb = this._formBuilder.group({ aa: aa }; I am trying to achieve the following: if (typeof(aa) == "Control") { // perform a specific action } else if (typeof(aa) == "ControlGroup") { // perform anoth ...

Utilizing Leaflet-geotiff in an Angular 6 Environment

I'm currently facing an issue where I am unable to display any .tif image on my map using the leaflet-geotiff plugin. I downloaded a file from gis-lab.info (you can download it from this link) and attempted to add it to my map, but I keep encountering ...

A method in TypeScript for defining a type as a combination of interfaces within a union, specified as [one of union of interfaces] & {//attributes}

// Here's a way to define types in TypeScript: interface SudoA { foo: string; } interface SudoB { bar: string; } type Sudo = SudoA | SudoB; type SuperSudo = Sudo & { super: boolean; } const baz: SuperSudo = { } // TypeScript (3. ...

Search for words in a given string that begin with the symbol $ using Angular 2

I am trying to locate words that begin with $. var str = "$hello, this is a $test $john #doe"; var re = /(?:^|\W)\$(\w+)(?!\w)/g, match, results = []; while (match = re.exec(str)) { results.push(match[1]); } The regular expression a ...

Ways to avoid Next.js from creating a singleton class/object multiple times

I developed a unique analytics tool that looks like this: class Analytics { data: Record<string, IData>; constructor() { this.data = {}; } setPaths(identifier: string) { if (!this.data[identifier]) this.da ...

What strategies can I employ to prevent redundancy when all my .vue files are identical?

Although I am new to Vue, there are many aspects that I find appealing. However, one thing I dislike is combining templates, scripts, and styles in the same file. Instead, I prefer separating these concerns by using: <template src="./template.html"> ...

Error: Unable to retrieve options using this.getOptions function. This issue is unrelated to Vue, it is occurring within

Required Modules "dependencies": { "express": "^4.17.1", "express-static-gzip": "^2.1.1", "react": "^17.0.2", "react-dom": "^17.0.2", "reac ...

Having trouble pinpointing the specific custom exception type when using the throw statement in TypeScript?

I have run into a problem while using a customized HttpException class in TypeScript. Let me show you how the class is structured: class HttpException extends Error { public status: number | undefined; public message: string; public data: any; ...

Exploring Angular 2: Incorporating multiple HTML pages into a single component

I am currently learning Angular 2 and have a component called Register. Within this single component, I have five different HTML pages. Is it possible to have multiple templates per component in order to navigate between these pages? How can I implement ro ...