Hone logo
Hone
Problems

Implementing a CanDeactivate Guard in Angular

Angular's CanDeactivate guard allows you to prevent navigation away from a component. This is crucial for scenarios where a user might be in the middle of filling out a form or performing an action that shouldn't be interrupted without saving or confirmation. This challenge asks you to implement a CanDeactivate guard that prompts the user to confirm navigation if they have unsaved changes in a component.

Problem Description

You need to create a CanDeactivate guard in Angular that checks for unsaved changes in a component before allowing navigation away from it. The guard should:

  1. Check for Unsaved Changes: The guard will receive a component as an argument. This component will have a method called hasUnsavedChanges() which returns a boolean indicating whether there are unsaved changes.
  2. Prompt the User: If hasUnsavedChanges() returns true, the guard should display a confirmation dialog to the user asking if they want to leave the page. The dialog should include a "Stay" and a "Leave" button.
  3. Handle User Response:
    • If the user clicks "Stay," navigation should be prevented, and the guard should return false.
    • If the user clicks "Leave," navigation should be allowed, and the guard should return true.
  4. Allow Navigation Without Confirmation: If hasUnsavedChanges() returns false, the guard should allow navigation without prompting the user and return true.

Expected Behavior:

  • When a user attempts to navigate away from a component with unsaved changes, a confirmation dialog appears.
  • If the user confirms they want to leave, navigation proceeds.
  • If the user chooses to stay, navigation is blocked.
  • If the component has no unsaved changes, navigation proceeds without interruption.

Edge Cases to Consider:

  • What happens if the component doesn't implement the hasUnsavedChanges() method? (Assume it should default to allowing navigation - true).
  • How should the dialog be displayed? (For simplicity, assume a basic alert is sufficient for this challenge, though a more sophisticated modal would be preferred in a real-world application).
  • What if the user cancels the navigation in some other way (e.g., closing the browser tab)? This is not a primary concern for this challenge.

Examples

Example 1:

Input: Component with hasUnsavedChanges() returning true. User attempts to navigate away.
Output: Confirmation dialog appears with "Stay" and "Leave" buttons. User clicks "Leave".
Explanation: Navigation proceeds.

Example 2:

Input: Component with hasUnsavedChanges() returning true. User attempts to navigate away.
Output: Confirmation dialog appears with "Stay" and "Leave" buttons. User clicks "Stay".
Explanation: Navigation is blocked.

Example 3:

Input: Component with hasUnsavedChanges() returning false. User attempts to navigate away.
Output: Navigation proceeds without any prompt.
Explanation: No confirmation dialog is displayed.

Constraints

  • The guard must be injectable and reusable across different components.
  • The hasUnsavedChanges() method is assumed to be present on the component being guarded. If not, default to allowing navigation.
  • Use a simple alert dialog for demonstration purposes. Do not implement a full-fledged modal.
  • The solution must be written in TypeScript and compatible with a standard Angular project setup.

Notes

  • Consider using Angular's dependency injection to provide the component to the guard.
  • The ActivatedRouteSnapshot and CanDeactivateFn<T> types are important for understanding the guard's context.
  • Think about how to handle the asynchronous nature of dialogs (although a simple alert is synchronous).
  • Focus on the core logic of checking for unsaved changes and prompting the user. Styling and advanced dialog implementations are outside the scope of this challenge.
Loading editor...
typescript