Skip to content

fix: emit afterClosed only after the native modal dismissal completes - #179

Merged
edusperoni merged 1 commit into
mainfrom
fix/dialog-after-closed-timing
Aug 24, 2026
Merged

fix: emit afterClosed only after the native modal dismissal completes#179
edusperoni merged 1 commit into
mainfrom
fix/dialog-after-closed-timing

Conversation

@edusperoni

Copy link
Copy Markdown
Collaborator

PR Checklist

What is the current behavior?

NativeDialogRef.afterClosed() is unreliable: it is usually emitted by a hardcoded 100ms fallback timer instead of the actual dismissal. On iOS the modal dismiss animation takes ~400–500ms, so afterClosed fires while the previous view controller is still being dismissed — opening another dialog from afterClosed then fails with Failed to open dialog: the modal view could not be presented, forcing apps to work around it with timeouts.

Additionally:

  • afterOpened() never fires (nothing ever emitted the 'opened' state).
  • Template-based dialogs dismissed natively (back button / swipe-down) never emit afterClosed at all.
  • The template-dialog close path decrements the modal navigation depth twice.

What is the new behavior?

afterClosed is now driven by core's showModal closeCallback, which fires only once the native dismissal has completed (on iOS, from the dismissViewControllerAnimated completion handler), followed by a one-shot unloaded listener attached only at that point — so an unrelated unload (e.g. the app going to the background) can never masquerade as a close. The old timer remains only as a 5s safety net for dismissals that never report completion.

  • Opening a new dialog from afterClosed now works without workarounds.
  • afterOpened() fires once the modal is fully presented (wired to shownModally).
  • Component and template portals share the same show/dismiss path, so natively-dismissed template dialogs now emit afterClosed, and _closeModalNavigation runs exactly once per close.
  • New native-dialog specs (passing on iOS and Android) assert the behavior: beforeClosedafterClosed ordering and result value, no ancestor still presenting at afterClosed time, an immediate no-timeout reopen, and native dismissal of both dialog types.

Note: afterClosed now fires at the real dismissal completion (~400–500ms on iOS) instead of ~100ms — intentionally later, since the earlier timing was a lie.

afterClosed was emitted by a hardcoded 100ms fallback timer while the iOS
dismissal animation (~400ms) was still running, so opening another dialog
from afterClosed failed with "the modal view could not be presented".

The 'closed' state is now driven by core's showModal closeCallback, which
fires once the native dismissal has completed, plus a one-shot 'unloaded'
listener scoped inside it so background-driven unloads can't masquerade as
a close. The timer remains only as a 5s safety net.

Both portal types now share the same show/dismiss path, which also makes
natively-dismissed template dialogs emit afterClosed, and afterOpened is
wired to shownModally (it never fired before).
@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f2084c8e-8b0e-48f9-9b4b-2789836220e1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Aug 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/NativeScript/angular/@nativescript/angular@179
npm i https://pkg.pr.new/NativeScript/angular/@nativescript/zone-js@179

commit: e4435a6

@edusperoni
edusperoni merged commit 1fcbca7 into main Aug 24, 2026
9 checks passed
@edusperoni
edusperoni deleted the fix/dialog-after-closed-timing branch August 24, 2026 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant