Hone logo
Hone
Problems

Angular Action Groups: Streamlining Component Interactions

Action groups in Angular provide a structured way to manage and execute actions related to a specific component or feature. This challenge focuses on building a reusable action group service that allows components to trigger and manage a set of predefined actions, promoting code organization and reducing boilerplate. Successfully completing this challenge will demonstrate your understanding of Angular services, dependency injection, and event handling.

Problem Description

You are tasked with creating an ActionGroupService that allows components to subscribe to and trigger actions within a defined group. The service should:

  1. Define Action Types: Allow the service to be initialized with a set of action types (strings).
  2. Register Actions: Provide a method to register actions, associating each action type with a function that will be executed when that action is triggered. The function should accept a payload (any data) as an argument.
  3. Trigger Actions: Provide a method to trigger an action by its type, passing in a payload.
  4. Subscribe to Actions: Provide a method to subscribe to actions, allowing components to react to specific action types and their payloads. Subscribers should receive the action type and payload.
  5. Unsubscribe from Actions: Provide a method to unsubscribe from actions.

Key Requirements:

  • The service should be reusable across multiple components.
  • Action registration should be dynamic – actions can be added after the service is created.
  • The service should handle multiple subscribers for each action type.
  • The service should prevent triggering actions that haven't been registered.

Expected Behavior:

  • When an action is triggered, all registered subscribers for that action type should receive the action type and payload.
  • Subscribers should be able to unsubscribe to stop receiving action notifications.
  • Attempting to trigger an unregistered action should result in a console warning (using console.warn).

Edge Cases to Consider:

  • What happens if an action is triggered with no payload?
  • What happens if a component tries to subscribe to an action type that doesn't exist? (Shouldn't throw an error, just not receive any notifications).
  • How to handle multiple components subscribing to the same action?

Examples

Example 1:

Input:
ActionGroupService initialized with action types: ['user.login', 'user.logout']
Action registered: 'user.login' -> (payload) => { console.log('User logged in:', payload); }
Action registered: 'user.logout' -> (payload) => { console.log('User logged out:', payload); }
Action triggered: 'user.login', payload: { username: 'testuser' }

Output:
Console: "User logged in: { username: 'testuser' }"

Explanation: The 'user.login' action is triggered, and the registered function is executed with the provided payload.

Example 2:

Input:
ActionGroupService initialized with action types: ['data.load', 'data.refresh']
Action registered: 'data.load' -> (payload) => { console.log('Data loaded:', payload); }
Component A subscribes to 'data.load'.
Component B subscribes to 'data.load'.
Action triggered: 'data.load', payload: { data: [1, 2, 3] }

Output:
Console: "Data loaded: { data: [ 1, 2, 3 ] }" (printed twice, once for each subscriber)

Explanation: The 'data.load' action is triggered, and both Component A and Component B receive the notification.

Example 3:

Input:
ActionGroupService initialized with action types: ['item.select']
Action triggered: 'unregistered.action', payload: 'some data'

Output:
Console: "Warning: Action 'unregistered.action' is not registered."

Explanation: An attempt to trigger an unregistered action results in a console warning.

Constraints

  • The service must be written in TypeScript.
  • The action types must be strings.
  • The payload can be of any type.
  • The service should be designed to be efficient and avoid unnecessary memory usage.
  • The service should not use RxJS operators beyond subscribe and unsubscribe.

Notes

  • Consider using a Map to store registered actions for efficient lookup.
  • Think about how to handle errors gracefully, especially when registering or triggering actions.
  • Focus on creating a clean, well-documented, and testable service.
  • The ActionGroupService should be injectable into Angular components.
  • The action types should be defined as constants to avoid typos and improve maintainability.
Loading editor...
typescript