ngx-bootstrap modal: How to get a return value from a modal?
Solution 1
Try like this :
myexample it's working correctly. hope this will help you
home.module.ts
import { ModalModule } from 'ngx-bootstrap';
@NgModule({
imports: [
ModalModule.forRoot()
]
})
home.component.html
<button class="btn btn-primary" (click)="openConfirmDialog()">Open Confirm box
</button>
home.component.ts
import { BsModalService } from 'ngx-bootstrap/modal';
import { BsModalRef } from 'ngx-bootstrap/modal/modal-options.class';
export class HomeComponent {
public modalRef: BsModalRef;
constructor(
private homeService: HomeService,
private modalService: BsModalService
) { }
openConfirmDialog() {
this.modalRef = this.modalService.show(HomeModalComponent);
this.modalRef.content.onClose.subscribe(result => {
console.log('results', result);
})
}
}
home-modal.component.html
<div class="alert-box">
<div class="modal-header">
<h4 class="modal-title">Confirm</h4>
<button type="button" class="close" aria-label="Close" (click)="bsModalRef.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Are you sure want to delete this node?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" (click)="onConfirm()">Yes</button>
<button type="button" class="btn btn-secondary" (click)="onCancel()">No</button>
</div>
</div>
home-modal.component.ts
import { Subject } from 'rxjs/Subject';
import { BsModalRef } from 'ngx-bootstrap/modal';
export class HomeModalComponent {
public onClose: Subject<boolean>;
constructor(private _bsModalRef: BsModalRef) { }
public ngOnInit(): void {
this.onClose = new Subject();
}
public onConfirm(): void {
this.onClose.next(true);
this._bsModalRef.hide();
}
public onCancel(): void {
this.onClose.next(false);
this._bsModalRef.hide();
}
}
Solution 2
I used the solution from @Chandru, however to return a true
or false
, instead of:
openConfirmDialog() {
this.modalRef = this.modalService.show(HomeModalComponent);
this.modalRef.content.onClose.subscribe(result => {
console.log('results', result);
})
}
I simply used:
openConfirmDialog() {
this.modalRef = this.modalService.show(HomeModalComponent);
return this.modalRef.content.onClose;
}
Solution 3
I understand that most of the answers above are completely valid, but that the main goal is be able to invoke the confirmation dialog in this way...
async openModalConfirmation() {
const result = await this.confirmationSvc.confirm('Confirm this...');
if (result) {
console.log('Yes!');
} else {
console.log('Oh no...');
}
}
Note that this is mostly syntactic sugar to simplify the use of a promise and the asynchronous stuff.
I think it's what the OP was looking for and probably can be reworked to support returning any other data type (apart from a boolean).
The rest of the code below (not including the template to keep this short), pretty straightforward..
ModalConfirmationService
import { ModalConfirmationComponent } from './component';
@Injectable()
export class ModalConfirmationService {
constructor(private bsModalService: BsModalService) {}
confirm(message: string): Promise<boolean> {
const modal = this.bsModalService.show(ModalConfirmationComponent, { initialState: { message: message }});
return new Promise<boolean>((resolve, reject) => modal.content.result.subscribe((result) => resolve(result) ));
}
}
ModalConfirmationComponent
import { Component, Input, Output, EventEmitter} from '@angular/core';
import { BsModalRef } from 'ngx-bootstrap/modal/bs-modal-ref.service';
import { Subject } from 'rxjs/Subject';
@Component({
templateUrl: './component.html'
})
export class ModalConfirmationComponent {
@Input() message: string;
result: Subject<boolean> = new Subject<boolean>();
constructor(public modalRef: BsModalRef) { }
confirm(): void {
this.result.next(true);
this.modalRef.hide();
}
decline(): void {
this.result.next(false);
this.modalRef.hide();
}
}
Solution 4
@ShinDarth You can add this function in your service and call this funcion whenever required.
In your Service, create this function
openConfirmDialogBox() {
this.modalRef = this.modalService.show(DemoModalComponent);
this.modalRef.content.action.take(1)
.subscribe((value) => {
console.log(value) // here value passed on clicking ok will be printed in console. Here true will be printed if OK is clicked
return value;
}, (err) => {
return false;
});
}
In your demo-modal.component.ts, create an EventEmitter
@Output() action = new EventEmitter();
public onClickOK() {
this.action.emit(true); //Can send your required data here instead of true
}
public onClickCANCEL() {
this.action.emit(false); //Can send your required data here instead of true
}
I hope this would help you
Solution 5
If you are using a later version of Angular you might get an error due to the location of BsModalRef that had moved:
Use this location:
import { BsModalRef } from 'ngx-bootstrap/modal/bs-modal-ref.service';
rather than:
import { BsModalRef } from 'ngx-bootstrap/modal/modal-options.class';
Related videos on Youtube
Comments
-
Francesco Borzi over 3 years
In my Angular 4 app, let's assume that I'm inside a service.
At some point, I want to ask the user for a confirmation, currently I'm doing it with just a
confirm(...)
request:const result = confirm('Are you sure?');
What if instead I would like to show an
ngx-bootstrap
modal with, let's say, two buttons "Yes" or "No" and obtain a similar result?
EDIT: in my case, I solved my issue by playing with Subjects. Here you can find my solution, in case it can be useful for someone else. However that solution does not solve this question which is about returning a value from a modal, so I leave it open.
-
tdragon over 6 yearsDid you try something so far?
-
Francesco Borzi over 6 yearsin my service I'm able to show the modal using
this.modalService.show(this.confirmModal)
but I don't know how to receive back the result of what the user clicked in the modal -
Chandru over 6 years@ShinDarth Just now only posted my answer.. i hope this will useful for you
-
-
Francesco Borzi over 6 yearsthanks for your answer, but how would you use it inside a service? For example inside a
CanDeactivate
method of a Guard that it is supposed to return true or false, without waiting? -
Francesco Borzi over 6 yearsI need to replace this with a modal:
canDeactivate() { return confirm( 'are you sure?' ); } }
-
RajeshKdev over 6 yearsGreat Solution :)
-
Hossein Bajan about 6 yearsYeeeeeeeeeeeees, thank you so muuuch :), It's working for me.
-
tatsu about 6 yearsthe
BsModalRef
path has changed fromngx-bootstrap/modal
tongx-bootstrap/modal/bs-modal-ref.service
-
Reza about 6 yearsGreat! How can I customize
Are you sure want to delete this node?
, I means passing it as param toopenConfirmDialog
-
Jason Krs about 6 yearsHow are you able to do
modalService.show(HomeModalComponent)
sinceHomeModalComponent
is the export from another class and therefore in another file ? -
tytyryty almost 6 years@RezaRahmati, to customize message you can in home-modal.component.html change test to {{message}} and then to call show like this:
const config = { message: 'Are you sure want to delete this node?'}; this.modalService.show(HomeModalComponent, { initialState: config });
-
Vinicius.Silva almost 6 yearsWhat happen with Subject subscribed inside 'openConfirmDialog' if user clicks on backdrop?
-
HDJEMAI almost 4 yearsWe need to unsubscribe ones we go to another screen: something like:
ngOnDestroy() { this.bsModalRef.content.onClose.unsubscribe(); }
To avoid memory leaks -
StNekroman Sama almost 4 yearsDoesn't cover dismiss by ESC key or click on backdrop.
-
Omkar over 2 yearsperfect solution, worked for me