Hone logo
Hone
Problems

Implementing Timeout Functionality in an Angular Component

Angular applications often require actions to be performed with a time limit. This challenge focuses on creating a reusable timeout mechanism within an Angular component, allowing you to execute a function after a specified delay and optionally cancel the timeout if needed. This is useful for scenarios like auto-logout, delayed data fetching, or temporary UI elements.

Problem Description

You need to implement a timeout functionality within an Angular component. This functionality should allow a user to:

  1. Set a timeout: Specify a delay (in milliseconds) after which a provided function should be executed.
  2. Execute a function: The provided function should be executed after the specified delay.
  3. Cancel the timeout (optional): Provide a mechanism to cancel the timeout before it expires, preventing the function from being executed.
  4. Return a timeout ID: Return a unique identifier (timeout ID) that can be used to cancel the timeout.

The solution should be encapsulated within a service to promote reusability across multiple components. The service should provide methods for setting a timeout, canceling a timeout, and potentially checking if a timeout is currently active.

Key Requirements:

  • The timeout should be implemented using JavaScript's setTimeout and clearTimeout functions.
  • The component should not directly manage the timeout; the timeout logic should be handled by the service.
  • The service should be injectable into Angular components.
  • The function to be executed after the timeout should be passed as an argument to the timeout setting function.
  • The timeout ID should be returned to the component for potential cancellation.

Expected Behavior:

  • When startTimeout is called with a delay and a function, setTimeout should be called, and the timeout ID should be returned.
  • If cancelTimeout is called with a timeout ID, clearTimeout should be called with that ID, preventing the function from executing.
  • If cancelTimeout is called with an invalid timeout ID (e.g., one that was never returned), the function should gracefully handle the error (e.g., by logging a warning).
  • If the timeout expires before being canceled, the provided function should be executed.

Edge Cases to Consider:

  • What happens if the delay is 0?
  • What happens if the function to be executed is null or undefined?
  • What happens if cancelTimeout is called multiple times with the same timeout ID?
  • What happens if cancelTimeout is called after the timeout has already expired and the function has executed?

Examples

Example 1:

Input: delay = 2000ms, function = () => console.log("Timeout expired!");
Output: timeoutId = 12345 (a unique number)
Explanation: A timeout is set to execute the provided function after 2 seconds. The timeout ID is returned.

Example 2:

Input: timeoutId = 12345, function = () => console.log("This won't execute");
Output: (No console log)
Explanation: The timeout with ID 12345 is canceled before it expires. The function is never executed.

Example 3: (Edge Case)

Input: delay = 0ms, function = () => console.log("Immediate execution");
Output: timeoutId = 67890 (a unique number)
Explanation: A timeout is set to execute the function immediately. The timeout ID is returned.

Constraints

  • The delay must be a non-negative integer (0 or greater).
  • The function to be executed must be a callable function (e.g., a function expression, arrow function, or method).
  • The timeout ID returned should be a number.
  • The service should be designed to be lightweight and efficient, minimizing overhead.
  • The service should handle potential errors gracefully, such as invalid timeout IDs.

Notes

Consider using RxJS Observables to manage the timeout lifecycle and provide more advanced features like retries or error handling. However, for this challenge, a simple implementation using setTimeout and clearTimeout is sufficient. Think about how to make the timeout service reusable and testable. Focus on clear and concise code.

Loading editor...
typescript