Passing data to a modal can be done using the initialState, but how can I receive data back? For instance, if I want to create a confirm dialog box?
Even though there's currently no built-in way to do that, it can be done by binding to the onHide/onHidden events.
The idea is to create an Observer that will subscribe to the onHidden event and fire next()
when it receives data from it.
I'm using the onHidden instead of the onHide so all CSS animations are done before the result is returned.
Also I implemented it in a MessageService
to keep a better separation of the code.
@Injectable()
export class MessageService {
bsModalRef: BsModalRef;
constructor(
private bsModalService: BsModalService,
) { }
confirm(title: string, message: string, options: string[]): Observable<string> {
const initialState = {
title: title,
message: message,
options: options,
};
this.bsModalRef = this.bsModalService.show(ConfirmDialogComponent, { initialState });
return new Observable<string>(this.getConfirmSubscriber());
}
private getConfirmSubscriber() {
return (observer) => {
const subscription = this.bsModalService.onHidden.subscribe((reason: string) => {
observer.next(this.bsModalRef.content.answer);
observer.complete();
});
return {
unsubscribe() {
subscription.unsubscribe();
}
};
}
}
}
The ConfirmDialogComponent looks like this:
export class ConfirmDialogComponent {
title: string;
message: string;
options: string[];
answer: string = "";
constructor(
public bsModalRef: BsModalRef,
) { }
respond(answer: string) {
this.answer = answer;
this.bsModalRef.hide();
}
}
After implemented, using it is very straight-forward:
confirm() {
this.messageService
.confirm(
"Confirmation dialog box",
"Are you sure you want to proceed?",
["Yes", "No"])
.subscribe((answer) => {
this.answers.push(answer);
});
}
You can get the full code and see it running in this demo.