Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { Location } from '@angular/common';
import { inject, Injectable } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Primitives } from '@decaf-ts/decorator-validation';
import { ComponentEventNames } from '@decaf-ts/ui-decorators';
import { NavigationOptions } from '@ionic/angular/common/providers/nav-controller';
import { NavController } from '@ionic/angular/standalone';
import { RouteDirections } from '../engine/constants';
import { KeyValue } from '../engine/types';
/**
* @description Service for handling routing operations in the application.
* @summary The RouterService provides a unified interface for navigation and route management,
* abstracting the underlying Angular Router and Ionic NavController functionality. It offers
* methods for navigating between routes, retrieving URL information, and managing query parameters.
* This service is designed to simplify navigation patterns and provide consistent behavior
* across the application.
*
* @class RouterService
* @injectable
*/
@Injectable({
providedIn: 'root',
})
export class NgxRouterService {
/**
* @description Stores the previous URL for back navigation.
* @summary Caches the previous URL from the router navigation events.
* This is used as a reference point for back navigation and for determining
* the navigation history of the application.
*
* @private
* @type {string}
* @memberOf RouterService
*/
private previousUrl!: string;
/**
* @description Angular Router service.
* @summary Injected Angular Router service that provides core navigation capabilities,
* URL manipulation, and navigation event handling. This service is used for most
* routing operations and for accessing information about the current route.
*
* @private
* @type {Router}
* @memberOf RouterService
*/
private router: Router = inject(Router);
/**
* @description Angular ActivatedRoute service.
* @summary Injected service that provides access to information about a route
* associated with a component loaded in an outlet. This service is used to
* access route parameters, query parameters, and other route-specific data.
*
* @private
* @type {ActivatedRoute}
* @memberOf RouterService
*/
private route: ActivatedRoute = inject(ActivatedRoute);
/**
* @description Ionic NavController service.
* @summary Injected Ionic service that provides methods for navigating between pages
* with animated transitions. This service extends Angular's routing capabilities
* with mobile-friendly navigation patterns and animations.
*
* @private
* @type {NavController}
* @memberOf RouterService
*/
private navController: NavController = inject(NavController);
/**
* @description Angular Location service.
* @summary Injected service that provides access to the browser's URL and history.
* This service is used for interacting with the browser's history API, allowing
* for back navigation and URL manipulation outside of Angular's router.
*
* @private
* @type {Location}
* @memberOf RouterService
*/
private location: Location = inject(Location);
/**
* @description Creates an instance of RouterService.
* @summary Initializes a new RouterService. The commented line suggests that in a previous
* version, this service was registered with an injectable registry system, which may have
* been used for dependency tracking or service discovery.
*
* @memberOf RouterService
*/
// constructor() {}
/**
* @description Parses query parameters from the current route.
* @summary Extracts specified query parameters from the current route and returns them
* as an array of key-value pairs. This method supports both single parameter and
* multiple parameter extraction, making it flexible for various use cases.
*
* @param {string | string[]} params - The parameter name(s) to extract from the route
* @return {KeyValue[]} An array of key-value objects representing the extracted parameters
*
* @mermaid
* sequenceDiagram
* participant C as Component
* participant R as RouterService
* participant A as ActivatedRoute
*
* C->>R: parseAllQueryParams(params)
* alt params is string
* R->>R: Convert params to array
* end
* R->>R: Initialize empty result array
* loop For each param in params
* R->>A: Get param value from queryParamMap
* A-->>R: Return param value or null
* R->>R: Create key-value object
* R->>R: Add to result array
* end
* R-->>C: Return array of key-value pairs
*
* @memberOf RouterService
*/
parseAllQueryParams(params?: string | string[]): KeyValue[] {
Iif (!params) {
params = Object.keys(this.route.snapshot.queryParams);
}
if (typeof params === Primitives.STRING) {
params = [params as string];
}
return (params as string[]).reduce((acc: KeyValue[], param: string) => {
const item = {
[param]: (this.route.snapshot.queryParamMap.get(param) as string) || null,
};
return [...acc, item];
}, []);
}
/**
* @description Checks if a query parameter exists in the current route.
* @summary Determines whether a specific query parameter is present in the current route's
* query parameters. This is useful for conditional logic based on the presence of
* certain parameters in the URL.
*
* @param {string} param - The name of the query parameter to check
* @return {boolean} True if the parameter exists, false otherwise
*
* @mermaid
* sequenceDiagram
* participant C as Component
* participant R as RouterService
* participant A as ActivatedRoute
*
* C->>R: hasQueryParam(param)
* R->>A: Access snapshot.queryParams
* R->>R: Check if param exists in queryParams
* R-->>C: Return boolean result
*
* @memberOf RouterService
*/
hasQueryParam(param: string): boolean {
return !!this.route.snapshot.queryParams?.[param];
}
/**
* @description Retrieves a specific query parameter from the current route.
* @summary Extracts a single query parameter from the current route and returns it
* as a key-value pair. This method leverages parseAllQueryParams internally and
* returns the first result or undefined if the parameter doesn't exist.
*
* @param {string} param - The name of the query parameter to retrieve
* @return {KeyValue | undefined} A key-value object representing the parameter, or undefined if not found
*
* @mermaid
* sequenceDiagram
* participant C as Component
* participant R as RouterService
*
* C->>R: getQueryParam(param)
* R->>R: parseAllQueryParams(param)
* R->>R: Extract first result or undefined
* R-->>C: Return key-value object or undefined
*
* @memberOf RouterService
*/
getQueryParam(param: string): KeyValue | undefined {
return this.parseAllQueryParams(param)?.[0] || undefined;
}
/**
* @description Retrieves the value of a specific query parameter.
* @summary Extracts the value of a single query parameter from the current route.
* This is a convenience method that handles the extraction and returns just the
* value rather than a key-value pair.
*
* @param {string} param - The name of the query parameter to retrieve
* @return {string | undefined} The value of the parameter, or undefined if not found
*
* @mermaid
* sequenceDiagram
* participant C as Component
* participant R as RouterService
*
* C->>R: getQueryParamValue(param)
* R->>R: parseAllQueryParams(param)
* R->>R: Extract value from first result or undefined
* R-->>C: Return string value or undefined
*
* @memberOf RouterService
*/
getQueryParamValue(param: string): string | undefined {
return (this.parseAllQueryParams(param)?.[0]?.[param] as string) || undefined;
}
/**
* @description Retrieves the last segment of the current URL.
* @summary Extracts the final path segment from the current URL, which often
* represents the current page or resource identifier. This method first attempts
* to use the Angular Router's URL, and falls back to the window location if needed.
*
* @return {string} The last segment of the current URL path
*
* @mermaid
* sequenceDiagram
* participant C as Component
* participant R as RouterService
* participant W as Window
*
* C->>R: getLastUrlSegment()
* alt Router URL available
* R->>R: Split router.url by '/'
* else Router URL not available
* R->>W: Get window.location.href
* R->>R: Split href by '/'
* end
* R->>R: Extract last segment
* R-->>C: Return last segment
*
* @memberOf RouterService
*/
getLastUrlSegment(): string {
return (this.router.url || globalThis.window.location.href).split('/').pop() as string;
}
/**
* @description Retrieves the current URL of the application.
* @summary Extracts the current URL path from either the Angular Router or the browser's
* window location, depending on availability. It also cleans the URL by removing the
* leading forward slash for consistency.
*
* @return {string} The current URL of the application without the leading slash
*
* @mermaid
* sequenceDiagram
* participant C as Component
* participant R as RouterService
* participant W as Window
*
* C->>R: getCurrentUrl()
* R->>R: Get router.url
* R->>W: Get window.location.pathname
* alt router.url is '/' and different from pathname
* R->>R: Use pathname
* else
* R->>R: Use router.url
* end
* R->>R: Remove leading '/'
* R-->>C: Return clean URL
*
* @memberOf RouterService
*/
getCurrentUrl(): string {
const routerUrl = this.router.url;
const pathName = globalThis.window?.location?.pathname;
const result = routerUrl === '/' && routerUrl !== pathName ? pathName : routerUrl;
return result.replace('/', '');
}
/**
* @description Retrieves the URL of the previous page.
* @summary Extracts the URL of the previous page from the router's navigation history.
* This information is useful for back navigation and for understanding the user's
* navigation path through the application.
*
* @return {string} The URL of the previous page
*
* @mermaid
* sequenceDiagram
* participant C as Component
* participant R as RouterService
* participant N as Router Navigation
*
* C->>R: getPreviousUrl()
* R->>N: Get currentNavigation
* alt previousNavigation exists
* R->>N: Extract previousNavigation.finalUrl
* R->>R: Store in previousUrl
* end
* R-->>C: Return previousUrl
*
* @memberOf RouterService
*/
getPreviousUrl(): string {
const currentNavigation = this.router.currentNavigation() || this.router.getCurrentNavigation();
Iif (!!currentNavigation && currentNavigation.previousNavigation?.finalUrl?.toString() !== undefined)
this.previousUrl = currentNavigation.previousNavigation?.finalUrl?.toString();
return this.previousUrl as string;
}
/**
* @description Navigates back to the previous page.
* @summary Triggers navigation back to the previous page in the browser's history.
* This method also dispatches a custom event to notify other components about
* the back navigation.
*
* @return {void}
*
* @mermaid
* sequenceDiagram
* participant C as Component
* participant R as RouterService
* participant L as Location
*
* C->>R: backToLastPage()
* R->>L: Dispatch BackButtonClickEvent event
* R->>L: Navigate back
*
* @memberOf RouterService
*/
backToLastPage(): void {
globalThis.window.dispatchEvent(
new CustomEvent(ComponentEventNames.BackButtonClickEvent, {
bubbles: true,
composed: true,
cancelable: false,
detail: { refres: true },
})
);
this.location.back();
}
/**
* @description Navigates to a specified page.
* @summary Triggers navigation to a specified page using the Ionic NavController.
* Supports different navigation directions and additional options.
*
* @param {string} page - The page to navigate to
* @param {RouteDirections} [direction=RouteDirections.FORWARD] - The direction of navigation
* @param {NavigationOptions} [options] - Additional navigation options
* @return {Promise<boolean>} A promise that resolves to true if navigation is successful, otherwise false
*
* @mermaid
* sequenceDiagram
* participant C as Component
* participant R as RouterService
* participant N as NavController
*
* C->>R: navigateTo(page, direction, options)
* alt direction is ROOT
* R->>N: navigateRoot(page, options)
* else direction is FORWARD
* R->>N: navigateForward(page, options)
* else direction is BACK
* R->>N: navigateBack(page, options)
* end
* N-->>R: Return navigation result
* R-->>C: Return boolean result
*
* @memberOf RouterService
*/
async navigateTo(
page: string,
direction: RouteDirections = RouteDirections.FORWARD,
options?: NavigationOptions
): Promise<boolean> {
Iif (direction === RouteDirections.ROOT) return this.navController.navigateRoot(page, options);
Iif (direction === RouteDirections.FORWARD) return await this.navController.navigateForward(page, options);
return await this.navController.navigateBack(page, options);
}
}
|