@one-paragon/angular-utilities 2.8.2 → 2.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/karma.conf.js +43 -0
  2. package/ng-package.json +7 -0
  3. package/package.json +15 -27
  4. package/src/action-state/action-state-spinner/action-state-spinner.component.css +16 -0
  5. package/src/action-state/action-state-spinner/action-state-spinner.component.html +7 -0
  6. package/src/action-state/action-state-spinner/action-state-spinner.component.spec.ts +25 -0
  7. package/src/action-state/action-state-spinner/action-state-spinner.component.ts +26 -0
  8. package/src/action-state/action-state-ui/action-state-ui.module.ts +13 -0
  9. package/src/action-state/index.ts +8 -0
  10. package/src/action-state/ngrx-ext/ngrx-ext.module.ts +14 -0
  11. package/src/action-state/ngrx.ts +69 -0
  12. package/src/http-request-state/RequestStateFactory.ts +56 -0
  13. package/src/http-request-state/RequestStateStore.ts +360 -0
  14. package/src/http-request-state/deprecated.ts +20 -0
  15. package/src/http-request-state/directives/HttpStateDirectiveBase.ts +29 -0
  16. package/src/http-request-state/directives/http-error-state-directive.ts +21 -0
  17. package/src/http-request-state/directives/http-inProgress-state-directive.ts +19 -0
  18. package/src/http-request-state/directives/http-notStarted-state-directive.ts +19 -0
  19. package/src/http-request-state/directives/http-success-state-directive.ts +29 -0
  20. package/src/http-request-state/directives/index.ts +5 -0
  21. package/src/http-request-state/directives/request-state-directive.spec.ts +73 -0
  22. package/src/http-request-state/directives/request-state-directive.ts +78 -0
  23. package/src/http-request-state/documentation/CREATE-REQUESTOR.md +667 -0
  24. package/src/http-request-state/documentation/README.md +191 -0
  25. package/src/http-request-state/documentation/REQUEST-STATE-STORE-CONFIG.md +648 -0
  26. package/src/http-request-state/documentation/REQUESTOR.md +616 -0
  27. package/src/http-request-state/helpers.ts +30 -0
  28. package/src/http-request-state/http-state-module.ts +23 -0
  29. package/src/http-request-state/index.ts +7 -0
  30. package/src/http-request-state/models/view-context.ts +18 -0
  31. package/src/http-request-state/observable.spec.ts +43 -0
  32. package/src/http-request-state/request-state.ts +66 -0
  33. package/src/http-request-state/rxjs/getRequestorBody.ts +10 -0
  34. package/src/http-request-state/rxjs/getRequestorState.ts +8 -0
  35. package/src/http-request-state/rxjs/index.ts +4 -0
  36. package/src/http-request-state/rxjs/tapError.ts +16 -0
  37. package/src/http-request-state/rxjs/tapSuccess.ts +16 -0
  38. package/src/http-request-state/strategies.spec.ts +42 -0
  39. package/src/http-request-state/types.ts +54 -0
  40. package/src/ngrx/actionable-selector.ts +189 -0
  41. package/src/ngrx/index.ts +1 -0
  42. package/src/public-api.ts +40 -0
  43. package/src/rxjs/defaultShareReplay.ts +8 -0
  44. package/src/rxjs/index.ts +5 -0
  45. package/src/rxjs/mapError.ts +8 -0
  46. package/src/rxjs/rxjs-operators.ts +130 -0
  47. package/src/rxjs/subjectifier.ts +17 -0
  48. package/src/rxjs/subscriber.directive.ts +57 -0
  49. package/src/specs/clickSubject.spec.ts +99 -0
  50. package/src/specs/dialog.spec.ts +101 -0
  51. package/src/specs/toggleGroupDirective.spec.ts +229 -0
  52. package/src/table-builder/classes/DefaultSettings.ts +11 -0
  53. package/src/table-builder/classes/MatTableObservableDataSource.ts +23 -0
  54. package/src/table-builder/classes/TableBuilderConfig.ts +49 -0
  55. package/src/table-builder/classes/TableBuilderDataSource.ts +64 -0
  56. package/src/table-builder/classes/TableState.ts +96 -0
  57. package/src/table-builder/classes/data-store.ts +10 -0
  58. package/src/table-builder/classes/display-col.ts +5 -0
  59. package/src/table-builder/classes/filter-info.ts +129 -0
  60. package/src/table-builder/classes/table-builder-general-settings.ts +233 -0
  61. package/src/table-builder/classes/table-builder.ts +105 -0
  62. package/src/table-builder/classes/table-store.helpers.ts +109 -0
  63. package/src/table-builder/classes/table-store.ts +540 -0
  64. package/src/table-builder/components/array-column.component.ts +34 -0
  65. package/src/table-builder/components/column-builder/column-builder.component.html +109 -0
  66. package/src/table-builder/components/column-builder/column-builder.component.scss +43 -0
  67. package/src/table-builder/components/column-builder/column-builder.component.spec.ts +49 -0
  68. package/src/table-builder/components/column-builder/column-builder.component.ts +130 -0
  69. package/src/table-builder/components/column-builder/column-helpers.ts +54 -0
  70. package/src/table-builder/components/column-header-menu/column-header-menu.component.html +128 -0
  71. package/src/table-builder/components/column-header-menu/column-header-menu.component.scss +97 -0
  72. package/src/table-builder/components/column-header-menu/column-header-menu.component.ts +113 -0
  73. package/src/table-builder/components/date-filter/date-filter.component.html +39 -0
  74. package/src/table-builder/components/date-filter/date-filter.component.ts +33 -0
  75. package/src/table-builder/components/date-time-filter/date-time-filter.component.html +25 -0
  76. package/src/table-builder/components/date-time-filter/date-time-filter.component.ts +33 -0
  77. package/src/table-builder/components/filter/filter.component.html +120 -0
  78. package/src/table-builder/components/filter/filter.component.scss +60 -0
  79. package/src/table-builder/components/filter/filter.component.spec.ts +86 -0
  80. package/src/table-builder/components/filter/filter.component.ts +73 -0
  81. package/src/table-builder/components/filter/in-list/in-list-filter.component.ts +171 -0
  82. package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.html +60 -0
  83. package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.scss +57 -0
  84. package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.ts +44 -0
  85. package/src/table-builder/components/generic-table/generic-table.component.html +140 -0
  86. package/src/table-builder/components/generic-table/generic-table.component.scss +45 -0
  87. package/src/table-builder/components/generic-table/generic-table.component.ts +531 -0
  88. package/src/table-builder/components/generic-table/paginator.component.ts +125 -0
  89. package/src/table-builder/components/group-by-list/group-by-list.component.css +24 -0
  90. package/src/table-builder/components/group-by-list/group-by-list.component.html +21 -0
  91. package/src/table-builder/components/group-by-list/group-by-list.component.spec.ts +23 -0
  92. package/src/table-builder/components/group-by-list/group-by-list.component.ts +26 -0
  93. package/src/table-builder/components/in-filter/in-filter.component.css +22 -0
  94. package/src/table-builder/components/in-filter/in-filter.component.html +38 -0
  95. package/src/table-builder/components/in-filter/in-filter.component.ts +66 -0
  96. package/src/table-builder/components/index.ts +9 -0
  97. package/src/table-builder/components/initialization-component/initialization.component.html +78 -0
  98. package/src/table-builder/components/initialization-component/initialization.component.ts +28 -0
  99. package/src/table-builder/components/link-column.component.ts +42 -0
  100. package/src/table-builder/components/number-filter/number-filter.component.css +10 -0
  101. package/src/table-builder/components/number-filter/number-filter.component.html +32 -0
  102. package/src/table-builder/components/number-filter/number-filter.component.spec.ts +30 -0
  103. package/src/table-builder/components/number-filter/number-filter.component.ts +34 -0
  104. package/src/table-builder/components/profiles-menu/profiles-menu.component.html +77 -0
  105. package/src/table-builder/components/profiles-menu/profiles-menu.component.scss +126 -0
  106. package/src/table-builder/components/profiles-menu/profiles-menu.component.spec.ts +23 -0
  107. package/src/table-builder/components/profiles-menu/profiles-menu.component.ts +64 -0
  108. package/src/table-builder/components/reset-menu/reset-menu.component.css +3 -0
  109. package/src/table-builder/components/reset-menu/reset-menu.component.html +10 -0
  110. package/src/table-builder/components/reset-menu/reset-menu.component.ts +87 -0
  111. package/src/table-builder/components/scroll-strategy.ts +139 -0
  112. package/src/table-builder/components/sort-menu/sort-menu.component-store.ts +57 -0
  113. package/src/table-builder/components/sort-menu/sort-menu.component.html +115 -0
  114. package/src/table-builder/components/sort-menu/sort-menu.component.scss +119 -0
  115. package/src/table-builder/components/sort-menu/sort-menu.component.ts +88 -0
  116. package/src/table-builder/components/table-container/table-container.component.html +94 -0
  117. package/src/table-builder/components/table-container/table-container.component.scss +60 -0
  118. package/src/table-builder/components/table-container/table-container.component.ts +467 -0
  119. package/src/table-builder/components/table-container/table-container.helpers/data-state.helpers.ts +113 -0
  120. package/src/table-builder/components/table-container/table-container.helpers/filter-state.helpers.ts +125 -0
  121. package/src/table-builder/components/table-container/table-container.helpers/groupBy.helpers.ts +172 -0
  122. package/src/table-builder/components/table-container/table-container.helpers/meta-data.helpers.ts +19 -0
  123. package/src/table-builder/components/table-container/table-container.helpers/sort-state.helpers.ts +47 -0
  124. package/src/table-builder/components/table-container/tableProps.ts +21 -0
  125. package/src/table-builder/components/table-container/virtual-scroll-container.ts +216 -0
  126. package/src/table-builder/components/table-container-filter/filter-list/filter-list.component.html +42 -0
  127. package/src/table-builder/components/table-container-filter/filter-list/filter-list.component.ts +47 -0
  128. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.css +40 -0
  129. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.html +11 -0
  130. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.spec.ts +85 -0
  131. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.ts +35 -0
  132. package/src/table-builder/components/table-container-filter/table-wrapper-filter-store.ts +13 -0
  133. package/src/table-builder/components/table-header-menu/table-header-menu.component.css +21 -0
  134. package/src/table-builder/components/table-header-menu/table-header-menu.component.html +48 -0
  135. package/src/table-builder/components/table-header-menu/table-header-menu.component.ts +36 -0
  136. package/src/table-builder/directives/custom-cell-directive.ts +63 -0
  137. package/src/table-builder/directives/custom-header-directive.ts +16 -0
  138. package/src/table-builder/directives/group-row-directive.ts +91 -0
  139. package/src/table-builder/directives/index.ts +8 -0
  140. package/src/table-builder/directives/multi-sort.directive.spec.ts +124 -0
  141. package/src/table-builder/directives/multi-sort.directive.ts +58 -0
  142. package/src/table-builder/directives/resize-column.directive.ts +107 -0
  143. package/src/table-builder/directives/table-wrapper.directive.ts +13 -0
  144. package/src/table-builder/directives/tb-filter.directive.ts +376 -0
  145. package/src/table-builder/documentation/table-builder/CUSTOM-CELL.md +568 -0
  146. package/src/table-builder/documentation/table-builder/CUSTOM-GROUP-ROW.md +356 -0
  147. package/src/table-builder/documentation/table-builder/METADATA-DOCUMENTATION.md +517 -0
  148. package/src/table-builder/documentation/table-builder/STYLER-STYLE.md +228 -0
  149. package/src/table-builder/documentation/table-builder/TABLE-BUILDER-CONFIG.md +325 -0
  150. package/src/table-builder/documentation/table-builder/TABLE-BUILDER-SETTINGS.md +515 -0
  151. package/src/table-builder/documentation/table-builder/TABLE-BUILDER.md +430 -0
  152. package/src/table-builder/documentation/table-builder/TABLE-CONTAINER.md +628 -0
  153. package/src/table-builder/enums/filterTypes.ts +39 -0
  154. package/src/table-builder/functions/boolean-filter-function.ts +12 -0
  155. package/src/table-builder/functions/date-filter-function.ts +85 -0
  156. package/src/table-builder/functions/download-data.ts +11 -0
  157. package/src/table-builder/functions/null-filter-function.ts +9 -0
  158. package/src/table-builder/functions/number-filter-function.ts +47 -0
  159. package/src/table-builder/functions/sort-data-function.ts +80 -0
  160. package/src/table-builder/functions/string-filter-function.ts +59 -0
  161. package/src/table-builder/interfaces/ColumnInfo.ts +9 -0
  162. package/src/table-builder/interfaces/dictionary.ts +3 -0
  163. package/src/table-builder/interfaces/meta-data.ts +279 -0
  164. package/src/table-builder/ngrx/tableBuilderStateStore.ts +203 -0
  165. package/src/table-builder/pipes/column-total.pipe.ts +16 -0
  166. package/src/table-builder/pipes/format-filter-type.pipe.ts +12 -0
  167. package/src/table-builder/pipes/format-filter-value.pipe.ts +71 -0
  168. package/src/table-builder/pipes/key-display.ts +13 -0
  169. package/src/table-builder/services/all-values-filter-creator.service.ts +92 -0
  170. package/src/table-builder/services/export-to-csv.service.ts +117 -0
  171. package/src/table-builder/services/link-creator.service.ts +98 -0
  172. package/src/table-builder/services/table-template-service.ts +47 -0
  173. package/src/table-builder/services/transform-creator.ts +90 -0
  174. package/src/table-builder/specs/table-custom-filters.spec.ts +262 -0
  175. package/src/table-builder/styles/collapser.styles.scss +16 -0
  176. package/src/table-builder/table-builder.module.ts +42 -0
  177. package/src/table-builder/types/group-types.ts +42 -0
  178. package/src/table-builder/types/index.ts +1 -0
  179. package/src/test.ts +17 -0
  180. package/src/utilities/array-helpers.ts +13 -0
  181. package/src/utilities/directives/auto-focus.directive.ts +20 -0
  182. package/src/utilities/directives/clickEmitterDirective.ts +15 -0
  183. package/src/utilities/directives/clickSubject.ts +19 -0
  184. package/src/utilities/directives/conditional-classes.directive.ts +36 -0
  185. package/src/utilities/directives/dialog-service.ts +19 -0
  186. package/src/utilities/directives/dialog.ts +174 -0
  187. package/src/utilities/directives/mat-toggle-group-directive.ts +60 -0
  188. package/src/utilities/directives/prevent-enter.directive.ts +12 -0
  189. package/src/utilities/directives/stop-propagation.directive.ts +19 -0
  190. package/src/utilities/directives/styler.ts +45 -0
  191. package/src/utilities/directives/trim-whitespace.directive.ts +20 -0
  192. package/src/utilities/index.ts +22 -0
  193. package/src/utilities/module.ts +53 -0
  194. package/src/utilities/pipes/function.pipe.ts +21 -0
  195. package/src/utilities/pipes/phone.pipe.ts +20 -0
  196. package/src/utilities/pipes/space-case.pipes.spec.ts +47 -0
  197. package/src/utilities/pipes/space-case.pipes.ts +29 -0
  198. package/tsconfig.lib.json +20 -0
  199. package/tsconfig.lib.prod.json +10 -0
  200. package/tsconfig.spec.json +17 -0
  201. package/fesm2022/one-paragon-angular-utilities.mjs +0 -7328
  202. package/fesm2022/one-paragon-angular-utilities.mjs.map +0 -1
  203. package/types/one-paragon-angular-utilities.d.ts +0 -2197
@@ -0,0 +1,648 @@
1
+ # RequestStateStoreConfig Documentation
2
+
3
+ ## Overview
4
+
5
+ `RequestStateStoreConfig` is a global configuration interface that allows you to set default error and success handlers for all requestors in your application. This is useful for establishing consistent error handling patterns, logging, notifications, or analytics across your entire application.
6
+
7
+ ## Interface Definition
8
+
9
+ ```typescript
10
+ export interface RequestStateStoreConfig {
11
+ /**
12
+ * if `useDefaultErrorHandler` is `true` this will run on each error if no other handler provided.
13
+ * else can be used by call `.useDefaultErrorHandler`
14
+ */
15
+ defaultErrorHandling?: (e?: any) => void;
16
+
17
+ /**
18
+ * if `useDefaultErrorHandler` is `true` `defaultErrorHandling` will run on each error if no other handler provided.
19
+ */
20
+ useDefaultErrorHandler?: boolean;
21
+
22
+ /**
23
+ * will be called if `useDefaultSuccess` is used
24
+ */
25
+ defaultSuccessHandling?: <T>(e?: T) => void;
26
+ }
27
+ ```
28
+
29
+ ## Injection Token
30
+
31
+ ```typescript
32
+ export const RequestStateStoreConfigToken = new InjectionToken<RequestStateStoreConfig>('RequestStateConfig');
33
+ ```
34
+
35
+ ## Configuration Properties
36
+
37
+ ### `defaultErrorHandling`
38
+
39
+ A function that handles errors globally for all requestors.
40
+
41
+ **Type:** `(e?: any) => void`
42
+
43
+ **Behavior:**
44
+ - If `useDefaultErrorHandler` is `true`, this runs automatically on every error unless a specific error handler is registered
45
+ - Can also be explicitly invoked by calling `.useDefaultErrorHandler()` on a requestor
46
+ - If not provided and `useDefaultErrorHandler()` is called, falls back to `console.error`
47
+
48
+ ### `useDefaultErrorHandler`
49
+
50
+ Controls whether the default error handler runs automatically for all requestors.
51
+
52
+ **Type:** `boolean`
53
+
54
+ **Behavior:**
55
+ - When `true`: Every requestor automatically uses `defaultErrorHandling` unless it has an explicit error handler (via `onError`, `onErrorResponse`, etc.)
56
+ - When `false` or `undefined`: Requestors only use the default handler if `.useDefaultErrorHandler()` is explicitly called
57
+
58
+ ### `defaultSuccessHandling`
59
+
60
+ A function that handles successful responses globally.
61
+
62
+ **Type:** `<T>(e?: T) => void`
63
+
64
+ **Behavior:**
65
+ - Only invoked when `.useDefaultSuccessHandler()` is explicitly called on a requestor
66
+ - If not provided and `useDefaultSuccessHandler()` is called, falls back to `console.log('Success')`
67
+
68
+ ## Providing Configuration
69
+
70
+ ### Standalone Application (app.config.ts)
71
+
72
+ ```typescript
73
+ import { ApplicationConfig } from '@angular/core';
74
+ import { RequestStateStoreConfigToken } from 'angular-utilities';
75
+
76
+ export const appConfig: ApplicationConfig = {
77
+ providers: [
78
+ {
79
+ provide: RequestStateStoreConfigToken,
80
+ useValue: {
81
+ defaultErrorHandling: (error) => {
82
+ console.error('Global Error Handler:', error);
83
+ // Add your global error handling logic
84
+ },
85
+ useDefaultErrorHandler: true,
86
+ defaultSuccessHandling: (response) => {
87
+ console.log('Global Success Handler:', response);
88
+ // Add your global success handling logic
89
+ }
90
+ }
91
+ },
92
+ // ... other providers
93
+ ]
94
+ };
95
+ ```
96
+
97
+ ### Module-based Application
98
+
99
+ ```typescript
100
+ import { NgModule } from '@angular/core';
101
+ import { RequestStateStoreConfigToken } from 'angular-utilities';
102
+
103
+ @NgModule({
104
+ providers: [
105
+ {
106
+ provide: RequestStateStoreConfigToken,
107
+ useValue: {
108
+ defaultErrorHandling: (error) => {
109
+ console.error('Global Error Handler:', error);
110
+ },
111
+ useDefaultErrorHandler: true
112
+ }
113
+ }
114
+ ]
115
+ })
116
+ export class AppModule { }
117
+ ```
118
+
119
+ ### Component-level Configuration
120
+
121
+ You can also provide configuration at the component level to override global settings for a specific component and its children.
122
+
123
+ ```typescript
124
+ import { Component } from '@angular/core';
125
+ import { RequestStateStoreConfigToken } from 'angular-utilities';
126
+
127
+ @Component({
128
+ selector: 'app-user-management',
129
+ template: `...`,
130
+ providers: [
131
+ {
132
+ provide: RequestStateStoreConfigToken,
133
+ useValue: {
134
+ defaultErrorHandling: (error) => {
135
+ // Component-specific error handling
136
+ console.error('User Management Error:', error);
137
+ },
138
+ useDefaultErrorHandler: false
139
+ }
140
+ }
141
+ ]
142
+ })
143
+ export class UserManagementComponent { }
144
+ ```
145
+
146
+ ## Usage Examples
147
+
148
+ ### Basic Global Error Handling
149
+
150
+ ```typescript
151
+ import { ApplicationConfig } from '@angular/core';
152
+ import { RequestStateStoreConfigToken } from 'angular-utilities';
153
+
154
+ export const appConfig: ApplicationConfig = {
155
+ providers: [
156
+ {
157
+ provide: RequestStateStoreConfigToken,
158
+ useValue: {
159
+ defaultErrorHandling: (error) => {
160
+ console.error('API Error:', error);
161
+ },
162
+ useDefaultErrorHandler: true
163
+ }
164
+ }
165
+ ]
166
+ };
167
+ ```
168
+
169
+ With this configuration, all requestors automatically log errors unless they have explicit error handlers:
170
+
171
+ ```typescript
172
+ // This requestor will automatically use the global error handler
173
+ const getUserRequestor = createRequestor(
174
+ (id: number) => this.http.get<User>(`/api/users/${id}`)
175
+ );
176
+
177
+ // This requestor will NOT use the global error handler (explicit handler registered)
178
+ const saveUserRequestor = createRequestor(
179
+ (user: User) => this.http.post<User>('/api/users', user)
180
+ ).onError((error) => {
181
+ console.log('Custom error handling for save');
182
+ });
183
+ ```
184
+
185
+ ### Integration with Toast/Snackbar Service
186
+
187
+ ```typescript
188
+ import { inject, ApplicationConfig } from '@angular/core';
189
+ import { RequestStateStoreConfigToken } from 'angular-utilities';
190
+ import { MatSnackBar } from '@angular/material/snackbar';
191
+
192
+ export const appConfig: ApplicationConfig = {
193
+ providers: [
194
+ {
195
+ provide: RequestStateStoreConfigToken,
196
+ useFactory: () => {
197
+ const snackBar = inject(MatSnackBar);
198
+
199
+ return {
200
+ defaultErrorHandling: (error) => {
201
+ const message = error?.message || 'An error occurred';
202
+ snackBar.open(message, 'Close', {
203
+ duration: 5000,
204
+ panelClass: ['error-snackbar']
205
+ });
206
+ },
207
+ useDefaultErrorHandler: true,
208
+ defaultSuccessHandling: () => {
209
+ snackBar.open('Operation completed successfully', 'Close', {
210
+ duration: 3000,
211
+ panelClass: ['success-snackbar']
212
+ });
213
+ }
214
+ };
215
+ }
216
+ }
217
+ ]
218
+ };
219
+ ```
220
+
221
+ ### Integration with Error Tracking Service
222
+
223
+ ```typescript
224
+ import { ApplicationConfig } from '@angular/core';
225
+ import { RequestStateStoreConfigToken } from 'angular-utilities';
226
+
227
+ export const appConfig: ApplicationConfig = {
228
+ providers: [
229
+ {
230
+ provide: RequestStateStoreConfigToken,
231
+ useFactory: () => {
232
+ const errorTracker = inject(ErrorTrackingService);
233
+ const logger = inject(LoggerService);
234
+
235
+ return {
236
+ defaultErrorHandling: (error) => {
237
+ // Log to console
238
+ console.error('API Error:', error);
239
+
240
+ // Track in analytics/monitoring service
241
+ errorTracker.captureException(error, {
242
+ context: 'HTTP Request',
243
+ level: 'error'
244
+ });
245
+
246
+ // Log to logging service
247
+ logger.error('Request failed', { error });
248
+ },
249
+ useDefaultErrorHandler: true
250
+ };
251
+ }
252
+ }
253
+ ]
254
+ };
255
+ ```
256
+
257
+ ### Conditional Error Handling
258
+
259
+ ```typescript
260
+ import { ApplicationConfig } from '@angular/core';
261
+ import { RequestStateStoreConfigToken } from 'angular-utilities';
262
+ import { HttpErrorResponse } from '@angular/common/http';
263
+
264
+ export const appConfig: ApplicationConfig = {
265
+ providers: [
266
+ {
267
+ provide: RequestStateStoreConfigToken,
268
+ useFactory: () => {
269
+ const router = inject(Router);
270
+ const notificationService = inject(NotificationService);
271
+
272
+ return {
273
+ defaultErrorHandling: (error: HttpErrorResponse) => {
274
+ // Handle different error types
275
+ if (error.status === 401) {
276
+ // Unauthorized - redirect to login
277
+ router.navigate(['/login']);
278
+ notificationService.warn('Your session has expired. Please log in again.');
279
+ } else if (error.status === 403) {
280
+ // Forbidden
281
+ notificationService.error('You do not have permission to perform this action.');
282
+ } else if (error.status === 404) {
283
+ // Not found
284
+ notificationService.warn('The requested resource was not found.');
285
+ } else if (error.status >= 500) {
286
+ // Server error
287
+ notificationService.error('A server error occurred. Please try again later.');
288
+ } else {
289
+ // Other errors
290
+ notificationService.error(error.message || 'An unexpected error occurred.');
291
+ }
292
+ },
293
+ useDefaultErrorHandler: true
294
+ };
295
+ }
296
+ }
297
+ ]
298
+ };
299
+ ```
300
+
301
+ ### Success Notifications
302
+
303
+ ```typescript
304
+ import { ApplicationConfig } from '@angular/core';
305
+ import { RequestStateStoreConfigToken } from 'angular-utilities';
306
+
307
+ export const appConfig: ApplicationConfig = {
308
+ providers: [
309
+ {
310
+ provide: RequestStateStoreConfigToken,
311
+ useFactory: () => {
312
+ const toastService = inject(ToastService);
313
+
314
+ return {
315
+ defaultSuccessHandling: () => {
316
+ toastService.success('Operation completed successfully!');
317
+ }
318
+ };
319
+ }
320
+ }
321
+ ]
322
+ };
323
+ ```
324
+
325
+ Then use it in requestors:
326
+
327
+ ```typescript
328
+ const saveRequestor = createRequestor(
329
+ (data: FormData) => this.http.post('/api/save', data)
330
+ ).useDefaultSuccessHandler();
331
+ // Will show "Operation completed successfully!" toast on success
332
+ ```
333
+
334
+ ## Requestor-level Control
335
+
336
+ Even with global configuration, individual requestors have full control over error handling behavior.
337
+
338
+ ### Explicit Error Handler (Overrides Global)
339
+
340
+ ```typescript
341
+ const requestor = createRequestor(
342
+ (id: number) => this.http.get<User>(`/api/users/${id}`)
343
+ ).onError((error) => {
344
+ // This explicit handler prevents the global handler from running
345
+ console.log('Custom error handling');
346
+ });
347
+ ```
348
+
349
+ ### Opt-in to Global Error Handler
350
+
351
+ ```typescript
352
+ const requestor = createRequestor(
353
+ (id: number) => this.http.get<User>(`/api/users/${id}`)
354
+ ).useDefaultErrorHandler();
355
+ // Explicitly uses the global error handler
356
+ ```
357
+
358
+ ### Opt-in to Global Success Handler
359
+
360
+ ```typescript
361
+ const requestor = createRequestor(
362
+ (id: number) => this.http.delete(`/api/users/${id}`)
363
+ ).useDefaultSuccessHandler();
364
+ // Explicitly uses the global success handler
365
+ ```
366
+
367
+ ### Combine Global and Custom Handlers
368
+
369
+ ```typescript
370
+ const requestor = createRequestor(
371
+ (id: number) => this.http.get<User>(`/api/users/${id}`)
372
+ )
373
+ .useDefaultErrorHandler() // Use global error handler
374
+ .onSuccess((user) => { // Add custom success handler
375
+ console.log('User loaded:', user.name);
376
+ });
377
+ ```
378
+
379
+ ## Error Handler Priority
380
+
381
+ The error handling priority is as follows:
382
+
383
+ 1. **Explicit error handlers** (`onError`, `onErrorResponse`, `onErrorRequest`, `onErrorWithRequest`) - Highest priority
384
+ 2. **Default error handler** (if `useDefaultErrorHandler: true` and no explicit handler) - Medium priority
385
+ 3. **No handling** - If neither explicit nor automatic default handling is configured
386
+
387
+ ```typescript
388
+ // Scenario 1: Explicit handler (highest priority)
389
+ createRequestor(...)
390
+ .onError((error) => { /* This runs */ });
391
+ // Global handler does NOT run (explicit handler registered)
392
+
393
+ // Scenario 2: Automatic default (useDefaultErrorHandler: true)
394
+ // Config: { useDefaultErrorHandler: true, defaultErrorHandling: ... }
395
+ createRequestor(...);
396
+ // Global defaultErrorHandling runs automatically
397
+
398
+ // Scenario 3: Explicit opt-in
399
+ // Config: { useDefaultErrorHandler: false, defaultErrorHandling: ... }
400
+ createRequestor(...)
401
+ .useDefaultErrorHandler();
402
+ // Global defaultErrorHandling runs because explicitly opted-in
403
+
404
+ // Scenario 4: No handling
405
+ // Config: { useDefaultErrorHandler: false }
406
+ createRequestor(...);
407
+ // No error handling occurs (errors are silent)
408
+ ```
409
+
410
+ ## Best Practices
411
+
412
+ ### 1. Always Provide Global Error Handling
413
+
414
+ Set up a global error handler to catch unexpected errors and prevent silent failures:
415
+
416
+ ```typescript
417
+ {
418
+ provide: RequestStateStoreConfigToken,
419
+ useValue: {
420
+ defaultErrorHandling: (error) => {
421
+ console.error('Unhandled request error:', error);
422
+ // Log to monitoring service
423
+ },
424
+ useDefaultErrorHandler: true
425
+ }
426
+ }
427
+ ```
428
+
429
+ ### 2. Use Different Handlers for Different Environments
430
+
431
+ ```typescript
432
+ import { environment } from './environments/environment';
433
+
434
+ {
435
+ provide: RequestStateStoreConfigToken,
436
+ useValue: {
437
+ defaultErrorHandling: (error) => {
438
+ if (environment.production) {
439
+ // Production: Send to monitoring service
440
+ errorTrackingService.captureException(error);
441
+ } else {
442
+ // Development: Detailed console logging
443
+ console.error('Development Error:', error);
444
+ console.table(error);
445
+ }
446
+ },
447
+ useDefaultErrorHandler: true
448
+ }
449
+ }
450
+ ```
451
+
452
+ ### 3. Provide User-Friendly Error Messages
453
+
454
+ Transform technical errors into user-friendly messages:
455
+
456
+ ```typescript
457
+ {
458
+ provide: RequestStateStoreConfigToken,
459
+ useFactory: () => {
460
+ const translate = inject(TranslateService);
461
+ const snackBar = inject(MatSnackBar);
462
+
463
+ return {
464
+ defaultErrorHandling: (error: HttpErrorResponse) => {
465
+ let message: string;
466
+
467
+ if (!navigator.onLine) {
468
+ message = translate.instant('errors.offline');
469
+ } else if (error.status === 0) {
470
+ message = translate.instant('errors.network');
471
+ } else {
472
+ message = translate.instant('errors.generic');
473
+ }
474
+
475
+ snackBar.open(message, 'OK', { duration: 5000 });
476
+ },
477
+ useDefaultErrorHandler: true
478
+ };
479
+ }
480
+ }
481
+ ```
482
+
483
+ ### 4. Combine Global and Specific Handlers
484
+
485
+ Use global handlers for common scenarios and specific handlers for special cases:
486
+
487
+ ```typescript
488
+ // Global handler catches most errors
489
+ // Config provides general error handling
490
+
491
+ // Specific handlers for special cases
492
+ const deleteUserRequestor = createRequestor(
493
+ (id: number) => this.http.delete(`/api/users/${id}`)
494
+ )
495
+ .onError((error) => {
496
+ if (error.status === 409) {
497
+ // Special handling for conflict errors
498
+ this.showConflictDialog();
499
+ } else {
500
+ // Let global handler take care of other errors
501
+ this.useDefaultErrorHandler();
502
+ }
503
+ });
504
+ ```
505
+
506
+ ### 5. Opt-out for Silent Operations
507
+
508
+ Some operations should fail silently without user notification:
509
+
510
+ ```typescript
511
+ // Prefetch request - don't show errors to users
512
+ const prefetchRequestor = createRequestor(
513
+ () => this.http.get('/api/prefetch-data')
514
+ );
515
+ // No error handler - fails silently even with useDefaultErrorHandler: true
516
+ // (because when an explicit handler is not set and useDefaultErrorHandler is true,
517
+ // the global handler runs - to truly silence, you'd need to add an empty handler)
518
+
519
+ // To truly silence:
520
+ const prefetchRequestor = createRequestor(
521
+ () => this.http.get('/api/prefetch-data')
522
+ ).onError(() => { /* Silent */ });
523
+ ```
524
+
525
+ ### 6. Log All Errors for Debugging
526
+
527
+ Even if you don't show all errors to users, always log them:
528
+
529
+ ```typescript
530
+ {
531
+ provide: RequestStateStoreConfigToken,
532
+ useFactory: () => {
533
+ const logger = inject(LoggerService);
534
+ const notificationService = inject(NotificationService);
535
+
536
+ return {
537
+ defaultErrorHandling: (error) => {
538
+ // Always log for debugging
539
+ logger.error('Request failed', { error });
540
+
541
+ // Only show to user for certain error types
542
+ if (error.status >= 400 && error.status < 500) {
543
+ notificationService.error('Please check your input and try again.');
544
+ }
545
+ },
546
+ useDefaultErrorHandler: true
547
+ };
548
+ }
549
+ }
550
+ ```
551
+
552
+ ## Testing with Configuration
553
+
554
+ ### Mocking Configuration in Tests
555
+
556
+ ```typescript
557
+ describe('UserComponent', () => {
558
+ let component: UserComponent;
559
+ let errorHandler: jasmine.Spy;
560
+
561
+ beforeEach(() => {
562
+ errorHandler = jasmine.createSpy('errorHandler');
563
+
564
+ TestBed.configureTestingModule({
565
+ declarations: [UserComponent],
566
+ imports: [HttpClientTestingModule],
567
+ providers: [
568
+ {
569
+ provide: RequestStateStoreConfigToken,
570
+ useValue: {
571
+ defaultErrorHandling: errorHandler,
572
+ useDefaultErrorHandler: true
573
+ }
574
+ }
575
+ ]
576
+ });
577
+
578
+ component = TestBed.createComponent(UserComponent).componentInstance;
579
+ });
580
+
581
+ it('should call global error handler on failure', () => {
582
+ const httpMock = TestBed.inject(HttpTestingController);
583
+
584
+ component.userRequestor.request(1);
585
+
586
+ const req = httpMock.expectOne('/api/users/1');
587
+ req.error(new ProgressEvent('error'), { status: 500 });
588
+
589
+ expect(errorHandler).toHaveBeenCalled();
590
+ });
591
+ });
592
+ ```
593
+
594
+ ### Testing Without Configuration
595
+
596
+ ```typescript
597
+ beforeEach(() => {
598
+ TestBed.configureTestingModule({
599
+ declarations: [UserComponent],
600
+ imports: [HttpClientTestingModule]
601
+ // No RequestStateStoreConfigToken provided
602
+ });
603
+ });
604
+
605
+ // Configuration is optional - tests work fine without it
606
+ ```
607
+
608
+ ## Migration Guide
609
+
610
+ ### Adding Configuration to Existing Application
611
+
612
+ If you're adding `RequestStateStoreConfig` to an application that already has requestors:
613
+
614
+ 1. **Add configuration gradually:**
615
+
616
+ ```typescript
617
+ // Start with useDefaultErrorHandler: false
618
+ {
619
+ provide: RequestStateStoreConfigToken,
620
+ useValue: {
621
+ defaultErrorHandling: (error) => {
622
+ console.warn('Unhandled error:', error);
623
+ },
624
+ useDefaultErrorHandler: false // Start with false
625
+ }
626
+ }
627
+ ```
628
+
629
+ 2. **Identify requestors without error handlers:**
630
+
631
+ Look for requestors that don't have `.onError()` calls.
632
+
633
+ 3. **Test the global handler:**
634
+
635
+ Temporarily add `.useDefaultErrorHandler()` to a few requestors to test.
636
+
637
+ 4. **Enable globally when ready:**
638
+
639
+ ```typescript
640
+ useDefaultErrorHandler: true // Enable for all
641
+ ```
642
+
643
+ ## See Also
644
+
645
+ - [Requestor Documentation](./REQUESTOR.md)
646
+ - [Error Handling Patterns](./REQUESTOR.md#error-handling)
647
+ - [Success Handling Patterns](./REQUESTOR.md#success-handling)
648
+ - [createRequestor Function](./CREATE-REQUESTOR.md)