Seeking a solitary undeniably corroborated statement from witnesses

I have implemented a messageBox functionality using p-toast. When a user clicks on delete, they are prompted with a yes or no option before hitting the API to delete the item. The issue I am facing is that if I click on the delete button for one item, select no, and then proceed to delete a different item by clicking yes, both the first and second items get deleted. I only want to delete the current item being clicked.

messagebox.service.ts:

public messageSource = new BehaviorSubject(false);   currentMessage =
 this.messageSource.asObservable();

   public _msgBoxSubject: EventEmitter<boolean> = new
 EventEmitter<boolean>();   public confirmResponse: boolean = false;  
 response: boolean = false;

   show() {
     this.messageSource.next(false);
     this.response = true;
     this._msgBoxSubject.emit(this.response);   }

   onYes(value) {
     this.messageSource.next(value);
     this.confirmResponse = value;   }

   onNo(value1) {
     this.confirmResponse = value1;   }

  hide() {
     this.response = false;
     this._msgBoxSubject.emit(this.response);   }

   getMsgBoxEmitter() {
     return this._msgBoxSubject;   }

messagebox.component.ts:

 ngOnInit() {
     this._msgBoxService.getMsgBoxEmitter().subscribe((value: boolean) => {
       this.messageService.clear();
       this.messageService.add({ key: 'c', sticky: true, severity: 'warn', summary: 'Are you sure?', detail: 'Confirm to proceed' });
     });    }

   onConfirm() {
     this.messageService.clear('c');
     this._msgBoxService.onYes(true);   }

   onReject() {
     this.messageService.clear('c');   }

emailmaster.component.ts: (I am calling this function on delete button click)

  deleteEmail(ID: Email) {
        this._msgBoxService.show();
        this._msgBoxService.currentMessage.subscribe(response1 => {
           if (response1 === true) {
             this._masterservice.deleteEmail(ID).subscribe(data => {
               this._toasterService.showMessage('Email deleted successfully', 'Success Message', 'success');
               if (data) {
                 this.GetEmails();
               }
             });
           }
        });
       }

I need to ensure that only the current item is deleted when the user clicks yes in the messagebox prompt.

Answer №1

It seems that the issue lies in the deleteEmail function where the subscription for currentMessage is not unsubscribed, causing it to persist from previous attempts.

deleteEmail(ID: Email) {
        this._msgBoxService.show();
        this._msgBoxService.currentMessage.subscribe(response1 => {
           if (response1 === true) {
             this._masterservice.deleteEmail(ID).subscribe(data => {
               this._toasterService.showMessage('Email deleted successfully', 'Success Message', 'success');
               if (data) {
                 this.GetEmails();
               }
             });
           }
        });
       }

This leads to the following scenario:

When you call deleteEmail, a confirmation pops up and your code subscribes to the answer waiting for a true response.

If you click no (false), the confirmation disappears but the subscribe continues to listen.

Subsequently calling deleteEmail results in another confirmation pop up and adds another subscribe, leading to multiple listeners.

If you now choose yes (true), both subscribes trigger delete requests for both the first and second item.


The suggestion made by another user was on the right track, but their approach won't work due to the service only emitting when something is true without indicating false. Therefore, some adjustments are needed to ensure proper functionality.

Here are the steps to follow:

Step 1: Utilize take(1)

this._msgBoxService.currentMessage
        .pipe(take(1)) 
        .subscribe(response1 => {

Step 2: Handle rejection

onReject() {
     this.messageService.clear('c');   
     this._msgBoxService.onNo(false);  

Step 3: Emit value on rejecting with onNo

onNo(value1) {
     this.messageSource.next(value1); 
     this.confirmResponse = value1;   

Additionally, remove emitting of false value on show for clarity

show() {
     this.response = true;

Answer №2

Your removeEmail function doesn't include the unsubscription from the currentMessage Observable. A possible solution could be:

removeEmail(ID: Email) {
  this._msgBoxService.display();
  this._msgBoxService.currentMessage.pipe(
    filter(response1 => response1), // only allows true values through
    take(1), // takes one emission per subscription and then completes
    mergeMap(() => this._masterservice.removeEmail(ID)), // mergeMap can be utilized safely as you're expecting a single emission
    tap(() => this._toasterService.showMessage('Email removed successfully', 'Success Message', 'success')),
    filter(data => !!data), // only emissions with existing data will proceed
    tap(() => this.GetEmails())
  ).subscribe();
}

In addition, it may be beneficial to incorporate error handling in case any part of this process fails. Consider implementing a catchError statement.

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

Is there a way to search for text and highlight it within an HTML string using Ionic

Welcome everyone! I am currently utilizing Ionic to load an article from a local HTML string. <ion-content padding> <p [innerHTML]="url"></p> </ion-content> The 'url' variable contains the local HTML string. My goal ...

Angular4: Automatically disable button after it is clicked within ngFor loop

I am facing the issue of disabling a <button> in an ngFor loop after it has been clicked by the user. Each button corresponds to an element in the loop, so I need to distinguish them using separate boolean values. Below is a snippet of the HTML code ...

Converting API response into a class instance using `class-transformer` in TypeScript: A step-by-step guide

When working with TypeScript, I have a regular method called Request(method: HttpMethod, url: string, ...) that is used for calling APIs. Now, my goal is to convert the response from this API request into an instance of a class using class-transformer (or ...

It is not possible to personalize color palettes on Material UI themes while using TypeScript

By customizing the Palette with additional properties, I create a type interface as shown below: declare module @material-ui/core/styles/createMuiTheme { interface PaletteColor { transparency?: string; customGradient?: PaletteColor; } interf ...

Ways to monitor modifications in an Angular4 service

Is there a way to monitor a variable or array within a service in order to identify any changes in its value or any additions to it? ...

The scrolling feature is not working in NativeScript's ScrollView component

As I delve into using NativeScript with Angular to develop my debut mobile application, things have been going quite smoothly. However, a recent snag has halted my progress - the page refuses to scroll to reveal its entire content. To showcase this issue, ...

What role does the empty object type {} play in typescript?

In the @types/React package of the DefinitelyTyped library, I came across this definition: interface FunctionComponent<P = {}> { (props: PropsWithChildren<P>, context?: any): ReactElement | null; propTypes?: WeakValidationMap&l ...

Executing npm / http-server script

I'm currently working on a shell script that will compile an Angular app using the "ng build" command and then launch a web server to host the app from the dist folder. The web server will be started with the "http-server" command, which needs to be i ...

Unable to simulate the Enter key press event for a text area using Angular 7

I've implemented a feature that allows users to type something and then press the submit button, at which point the cursor should move to the next line. If the user types some words and presses the Enter key, the cursor should also shift to the next l ...

Guide to making an array of objects reactively with formControlName

I am currently working with an Angular application. Within this application, I have a reactive form that is declared as form!: FormGroup<GlobalBean> Within the GlobalBean interface, there is an array of another bean defined as: export interface Glo ...

Incorporate personalized elements into your @react-three/fiber environment

My dilemma lies in the fact that I am trying to incorporate my custom components into my scene. However, these custom components are defined in a separate file. When I attempt to define my custom component, I encounter an error message stating: Cannot find ...

Using command line arguments in a Tauri project with a Next.js frontend

I am utilizing Tauri.JS in conjunction with Next.js. In this scenario, I need to execute the console command: npm run tauri dev --<argument name>=<some value>. Afterwards, I should be able to access the value of the argument in my JavaScript ...

Issues persist with the implementation of async in Angular2+

In my Angular2+ component, I created a function that outputs the results before actually running the function. This causes the desired output to appear later than expected. The function sends a variable parameter with an HTTP request to a NodeJS backend an ...

What improvements can I make to enhance my method?

I have a block of code that I'm looking to clean up and streamline for better efficiency. My main goal is to remove the multiple return statements within the method. Any suggestions on how I might refactor this code? Are there any design patterns th ...

What causes the website to malfunction when I refresh the page?

I utilized a Fuse template to construct my angular project. However, upon reloading the page, I encountered broken website elements. The error message displayed is as follows: Server Error 404 - File or directory not found. The resource you are looking fo ...

Is it possible to simultaneously update two entities using a single endpoint?

In order to update data in two different entities with a @OneToOne relationship between UserEntity and DetailsEntity, I need to create a function in my service that interacts with the database. Here are the entity definitions: UserEntity @Entity() export ...

What is the proper way to specify the interface as Dispatch<Action>?

My goal is to create an interface with the dispatch function without using Redux. interface DispatchProps { dispatch: (action: { type: string }) => void; } export function addTwoToNumber({ dispatch }: DispatchProps) { dispatch({ type: '@addTwo ...

How can the service receive the return value from a subscribed subject?

I have a question about whether it is possible to retrieve the value from a call to Subject.next(). Can you suggest any other approaches on how to receive a response in the given scenario? My current situation involves a notify service that is used throug ...

How to programmatically close a ngbDatePicker popup in Angular using TypeScript

I am currently working with Angular 9 and Ng-Bootstrap, encountering an issue with my ngb-datepicker. I have implemented a Range datepicker in a popup and would like it to close automatically when a range is selected. The problem arises because I want to ...

I'm curious about the location of sqlite data storage in Ionic when utilizing SqlStorage

I'm simply intrigued by the default key-value usage in this code snippet. import {Storage, SqlStorage } from 'ionic-angular'; let storage = new Storage(SqlStorage); storage.set(key, value); storage.get(key).then((value) => { ... }); Wh ...