@one-paragon/angular-utilities 2.8.4 → 2.8.6

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/fesm2022/one-paragon-angular-utilities.mjs +7350 -0
  2. package/fesm2022/one-paragon-angular-utilities.mjs.map +1 -0
  3. package/package.json +27 -15
  4. package/types/one-paragon-angular-utilities.d.ts +2211 -0
  5. package/karma.conf.js +0 -43
  6. package/ng-package.json +0 -7
  7. package/src/action-state/action-state-spinner/action-state-spinner.component.css +0 -16
  8. package/src/action-state/action-state-spinner/action-state-spinner.component.html +0 -7
  9. package/src/action-state/action-state-spinner/action-state-spinner.component.spec.ts +0 -25
  10. package/src/action-state/action-state-spinner/action-state-spinner.component.ts +0 -26
  11. package/src/action-state/action-state-ui/action-state-ui.module.ts +0 -13
  12. package/src/action-state/index.ts +0 -8
  13. package/src/action-state/ngrx-ext/ngrx-ext.module.ts +0 -14
  14. package/src/action-state/ngrx.ts +0 -69
  15. package/src/http-request-state/RequestStateFactory.ts +0 -56
  16. package/src/http-request-state/RequestStateStore.ts +0 -360
  17. package/src/http-request-state/deprecated.ts +0 -20
  18. package/src/http-request-state/directives/HttpStateDirectiveBase.ts +0 -29
  19. package/src/http-request-state/directives/http-error-state-directive.ts +0 -21
  20. package/src/http-request-state/directives/http-inProgress-state-directive.ts +0 -19
  21. package/src/http-request-state/directives/http-notStarted-state-directive.ts +0 -19
  22. package/src/http-request-state/directives/http-success-state-directive.ts +0 -29
  23. package/src/http-request-state/directives/index.ts +0 -5
  24. package/src/http-request-state/directives/request-state-directive.spec.ts +0 -73
  25. package/src/http-request-state/directives/request-state-directive.ts +0 -78
  26. package/src/http-request-state/documentation/CREATE-REQUESTOR.md +0 -667
  27. package/src/http-request-state/documentation/README.md +0 -191
  28. package/src/http-request-state/documentation/REQUEST-STATE-STORE-CONFIG.md +0 -648
  29. package/src/http-request-state/documentation/REQUESTOR.md +0 -616
  30. package/src/http-request-state/helpers.ts +0 -30
  31. package/src/http-request-state/http-state-module.ts +0 -23
  32. package/src/http-request-state/index.ts +0 -7
  33. package/src/http-request-state/models/view-context.ts +0 -18
  34. package/src/http-request-state/observable.spec.ts +0 -43
  35. package/src/http-request-state/request-state.ts +0 -66
  36. package/src/http-request-state/rxjs/getRequestorBody.ts +0 -10
  37. package/src/http-request-state/rxjs/getRequestorState.ts +0 -8
  38. package/src/http-request-state/rxjs/index.ts +0 -4
  39. package/src/http-request-state/rxjs/tapError.ts +0 -16
  40. package/src/http-request-state/rxjs/tapSuccess.ts +0 -16
  41. package/src/http-request-state/strategies.spec.ts +0 -42
  42. package/src/http-request-state/types.ts +0 -54
  43. package/src/ngrx/actionable-selector.ts +0 -189
  44. package/src/ngrx/index.ts +0 -1
  45. package/src/public-api.ts +0 -40
  46. package/src/rxjs/defaultShareReplay.ts +0 -8
  47. package/src/rxjs/index.ts +0 -5
  48. package/src/rxjs/mapError.ts +0 -8
  49. package/src/rxjs/rxjs-operators.ts +0 -130
  50. package/src/rxjs/subjectifier.ts +0 -17
  51. package/src/rxjs/subscriber.directive.ts +0 -57
  52. package/src/specs/clickSubject.spec.ts +0 -99
  53. package/src/specs/dialog.spec.ts +0 -101
  54. package/src/specs/toggleGroupDirective.spec.ts +0 -229
  55. package/src/table-builder/classes/DefaultSettings.ts +0 -11
  56. package/src/table-builder/classes/MatTableObservableDataSource.ts +0 -23
  57. package/src/table-builder/classes/TableBuilderConfig.ts +0 -49
  58. package/src/table-builder/classes/TableBuilderDataSource.ts +0 -64
  59. package/src/table-builder/classes/TableState.ts +0 -96
  60. package/src/table-builder/classes/data-store.ts +0 -10
  61. package/src/table-builder/classes/display-col.ts +0 -5
  62. package/src/table-builder/classes/filter-info.ts +0 -129
  63. package/src/table-builder/classes/table-builder-general-settings.ts +0 -233
  64. package/src/table-builder/classes/table-builder.ts +0 -105
  65. package/src/table-builder/classes/table-store.helpers.ts +0 -109
  66. package/src/table-builder/classes/table-store.ts +0 -540
  67. package/src/table-builder/components/array-column.component.ts +0 -34
  68. package/src/table-builder/components/column-builder/column-builder.component.html +0 -109
  69. package/src/table-builder/components/column-builder/column-builder.component.scss +0 -43
  70. package/src/table-builder/components/column-builder/column-builder.component.spec.ts +0 -49
  71. package/src/table-builder/components/column-builder/column-builder.component.ts +0 -130
  72. package/src/table-builder/components/column-builder/column-helpers.ts +0 -54
  73. package/src/table-builder/components/column-header-menu/column-header-menu.component.html +0 -128
  74. package/src/table-builder/components/column-header-menu/column-header-menu.component.scss +0 -97
  75. package/src/table-builder/components/column-header-menu/column-header-menu.component.ts +0 -113
  76. package/src/table-builder/components/date-filter/date-filter.component.html +0 -39
  77. package/src/table-builder/components/date-filter/date-filter.component.ts +0 -33
  78. package/src/table-builder/components/date-time-filter/date-time-filter.component.html +0 -25
  79. package/src/table-builder/components/date-time-filter/date-time-filter.component.ts +0 -33
  80. package/src/table-builder/components/filter/filter.component.html +0 -120
  81. package/src/table-builder/components/filter/filter.component.scss +0 -60
  82. package/src/table-builder/components/filter/filter.component.spec.ts +0 -86
  83. package/src/table-builder/components/filter/filter.component.ts +0 -73
  84. package/src/table-builder/components/filter/in-list/in-list-filter.component.ts +0 -171
  85. package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.html +0 -60
  86. package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.scss +0 -57
  87. package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.ts +0 -44
  88. package/src/table-builder/components/generic-table/generic-table.component.html +0 -140
  89. package/src/table-builder/components/generic-table/generic-table.component.scss +0 -45
  90. package/src/table-builder/components/generic-table/generic-table.component.ts +0 -531
  91. package/src/table-builder/components/generic-table/paginator.component.ts +0 -125
  92. package/src/table-builder/components/group-by-list/group-by-list.component.css +0 -24
  93. package/src/table-builder/components/group-by-list/group-by-list.component.html +0 -21
  94. package/src/table-builder/components/group-by-list/group-by-list.component.spec.ts +0 -23
  95. package/src/table-builder/components/group-by-list/group-by-list.component.ts +0 -26
  96. package/src/table-builder/components/in-filter/in-filter.component.css +0 -22
  97. package/src/table-builder/components/in-filter/in-filter.component.html +0 -38
  98. package/src/table-builder/components/in-filter/in-filter.component.ts +0 -66
  99. package/src/table-builder/components/index.ts +0 -9
  100. package/src/table-builder/components/initialization-component/initialization.component.html +0 -78
  101. package/src/table-builder/components/initialization-component/initialization.component.ts +0 -28
  102. package/src/table-builder/components/link-column.component.ts +0 -42
  103. package/src/table-builder/components/number-filter/number-filter.component.css +0 -10
  104. package/src/table-builder/components/number-filter/number-filter.component.html +0 -32
  105. package/src/table-builder/components/number-filter/number-filter.component.spec.ts +0 -30
  106. package/src/table-builder/components/number-filter/number-filter.component.ts +0 -34
  107. package/src/table-builder/components/profiles-menu/profiles-menu.component.html +0 -77
  108. package/src/table-builder/components/profiles-menu/profiles-menu.component.scss +0 -126
  109. package/src/table-builder/components/profiles-menu/profiles-menu.component.spec.ts +0 -23
  110. package/src/table-builder/components/profiles-menu/profiles-menu.component.ts +0 -64
  111. package/src/table-builder/components/reset-menu/reset-menu.component.css +0 -3
  112. package/src/table-builder/components/reset-menu/reset-menu.component.html +0 -10
  113. package/src/table-builder/components/reset-menu/reset-menu.component.ts +0 -87
  114. package/src/table-builder/components/scroll-strategy.ts +0 -139
  115. package/src/table-builder/components/sort-menu/sort-menu.component-store.ts +0 -57
  116. package/src/table-builder/components/sort-menu/sort-menu.component.html +0 -115
  117. package/src/table-builder/components/sort-menu/sort-menu.component.scss +0 -119
  118. package/src/table-builder/components/sort-menu/sort-menu.component.ts +0 -88
  119. package/src/table-builder/components/table-container/table-container.component.html +0 -94
  120. package/src/table-builder/components/table-container/table-container.component.scss +0 -60
  121. package/src/table-builder/components/table-container/table-container.component.ts +0 -467
  122. package/src/table-builder/components/table-container/table-container.helpers/data-state.helpers.ts +0 -113
  123. package/src/table-builder/components/table-container/table-container.helpers/filter-state.helpers.ts +0 -125
  124. package/src/table-builder/components/table-container/table-container.helpers/groupBy.helpers.ts +0 -172
  125. package/src/table-builder/components/table-container/table-container.helpers/meta-data.helpers.ts +0 -19
  126. package/src/table-builder/components/table-container/table-container.helpers/sort-state.helpers.ts +0 -47
  127. package/src/table-builder/components/table-container/tableProps.ts +0 -21
  128. package/src/table-builder/components/table-container/virtual-scroll-container.ts +0 -216
  129. package/src/table-builder/components/table-container-filter/filter-list/filter-list.component.html +0 -42
  130. package/src/table-builder/components/table-container-filter/filter-list/filter-list.component.ts +0 -47
  131. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.css +0 -40
  132. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.html +0 -11
  133. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.spec.ts +0 -85
  134. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.ts +0 -35
  135. package/src/table-builder/components/table-container-filter/table-wrapper-filter-store.ts +0 -13
  136. package/src/table-builder/components/table-header-menu/table-header-menu.component.css +0 -21
  137. package/src/table-builder/components/table-header-menu/table-header-menu.component.html +0 -48
  138. package/src/table-builder/components/table-header-menu/table-header-menu.component.ts +0 -36
  139. package/src/table-builder/directives/custom-cell-directive.ts +0 -63
  140. package/src/table-builder/directives/custom-header-directive.ts +0 -16
  141. package/src/table-builder/directives/group-row-directive.ts +0 -91
  142. package/src/table-builder/directives/index.ts +0 -8
  143. package/src/table-builder/directives/multi-sort.directive.spec.ts +0 -124
  144. package/src/table-builder/directives/multi-sort.directive.ts +0 -58
  145. package/src/table-builder/directives/resize-column.directive.ts +0 -107
  146. package/src/table-builder/directives/table-wrapper.directive.ts +0 -13
  147. package/src/table-builder/directives/tb-filter.directive.ts +0 -376
  148. package/src/table-builder/documentation/table-builder/CUSTOM-CELL.md +0 -568
  149. package/src/table-builder/documentation/table-builder/CUSTOM-GROUP-ROW.md +0 -356
  150. package/src/table-builder/documentation/table-builder/METADATA-DOCUMENTATION.md +0 -517
  151. package/src/table-builder/documentation/table-builder/STYLER-STYLE.md +0 -228
  152. package/src/table-builder/documentation/table-builder/TABLE-BUILDER-CONFIG.md +0 -325
  153. package/src/table-builder/documentation/table-builder/TABLE-BUILDER-SETTINGS.md +0 -515
  154. package/src/table-builder/documentation/table-builder/TABLE-BUILDER.md +0 -430
  155. package/src/table-builder/documentation/table-builder/TABLE-CONTAINER.md +0 -628
  156. package/src/table-builder/enums/filterTypes.ts +0 -39
  157. package/src/table-builder/functions/boolean-filter-function.ts +0 -12
  158. package/src/table-builder/functions/date-filter-function.ts +0 -85
  159. package/src/table-builder/functions/download-data.ts +0 -11
  160. package/src/table-builder/functions/null-filter-function.ts +0 -9
  161. package/src/table-builder/functions/number-filter-function.ts +0 -47
  162. package/src/table-builder/functions/sort-data-function.ts +0 -80
  163. package/src/table-builder/functions/string-filter-function.ts +0 -59
  164. package/src/table-builder/interfaces/ColumnInfo.ts +0 -9
  165. package/src/table-builder/interfaces/dictionary.ts +0 -3
  166. package/src/table-builder/interfaces/meta-data.ts +0 -279
  167. package/src/table-builder/ngrx/tableBuilderStateStore.ts +0 -203
  168. package/src/table-builder/pipes/column-total.pipe.ts +0 -16
  169. package/src/table-builder/pipes/format-filter-type.pipe.ts +0 -12
  170. package/src/table-builder/pipes/format-filter-value.pipe.ts +0 -71
  171. package/src/table-builder/pipes/key-display.ts +0 -13
  172. package/src/table-builder/services/all-values-filter-creator.service.ts +0 -92
  173. package/src/table-builder/services/export-to-csv.service.ts +0 -117
  174. package/src/table-builder/services/link-creator.service.ts +0 -98
  175. package/src/table-builder/services/table-template-service.ts +0 -47
  176. package/src/table-builder/services/transform-creator.ts +0 -90
  177. package/src/table-builder/specs/table-custom-filters.spec.ts +0 -262
  178. package/src/table-builder/styles/collapser.styles.scss +0 -16
  179. package/src/table-builder/table-builder.module.ts +0 -42
  180. package/src/table-builder/types/group-types.ts +0 -42
  181. package/src/table-builder/types/index.ts +0 -1
  182. package/src/test.ts +0 -17
  183. package/src/utilities/array-helpers.ts +0 -13
  184. package/src/utilities/directives/auto-focus.directive.ts +0 -20
  185. package/src/utilities/directives/clickEmitterDirective.ts +0 -15
  186. package/src/utilities/directives/clickSubject.ts +0 -19
  187. package/src/utilities/directives/conditional-classes.directive.ts +0 -36
  188. package/src/utilities/directives/dialog-service.ts +0 -19
  189. package/src/utilities/directives/dialog.ts +0 -174
  190. package/src/utilities/directives/mat-toggle-group-directive.ts +0 -60
  191. package/src/utilities/directives/prevent-enter.directive.ts +0 -12
  192. package/src/utilities/directives/stop-propagation.directive.ts +0 -19
  193. package/src/utilities/directives/styler.ts +0 -45
  194. package/src/utilities/directives/trim-whitespace.directive.ts +0 -20
  195. package/src/utilities/index.ts +0 -22
  196. package/src/utilities/module.ts +0 -53
  197. package/src/utilities/pipes/function.pipe.ts +0 -21
  198. package/src/utilities/pipes/phone.pipe.ts +0 -20
  199. package/src/utilities/pipes/space-case.pipes.spec.ts +0 -47
  200. package/src/utilities/pipes/space-case.pipes.ts +0 -29
  201. package/tsconfig.lib.json +0 -20
  202. package/tsconfig.lib.prod.json +0 -10
  203. package/tsconfig.spec.json +0 -17
@@ -1,667 +0,0 @@
1
- # createRequestor Function Documentation
2
-
3
- ## Overview
4
-
5
- `createRequestor` is a standalone function that creates a `RequestStateStore` instance (requestor) for managing HTTP request state in Angular applications. It provides a convenient way to create requestors outside of the Angular dependency injection context, making it ideal for use in components, services, and other contexts.
6
-
7
- ## Function Signature
8
-
9
- ```typescript
10
- // Basic usage - no projection
11
- function createRequestor<TParam extends any[], V>(
12
- req: RequestFactory<TParam, V>,
13
- options?: RequestCreatorOptions<TParam>
14
- ): RequestStateStore<TParam, V>
15
-
16
- // With projection - transforms the response
17
- function createRequestor<TParam extends any[], V, R, T = R>(
18
- req: RequestFactory<TParam, V>,
19
- project: (v: V) => R,
20
- options?: RequestCreatorOptions<TParam>
21
- ): RequestStateStore<TParam, V, T>
22
- ```
23
-
24
- ### Type Parameters
25
-
26
- - **`TParam`**: Array type representing the parameters the request function accepts (e.g., `[number]`, `[string, number]`)
27
- - **`V`**: The raw response type returned by the HTTP request (e.g., `UserDTO`)
28
- - **`R`**: The projected/transformed response type (only when using projection)
29
- - **`T`**: The final type stored in state (defaults to `V` without projection, or `R` with projection)
30
-
31
- ### Parameters
32
-
33
- - **`req`**: A function that takes parameters and returns an `Observable`. Typically an HTTP request.
34
- ```typescript
35
- RequestFactory<TParam, V> = (...params: [...TParam]) => Observable<V>
36
- ```
37
-
38
- - **`project`** _(optional)_: A transformation function to map the raw response to a different type.
39
- ```typescript
40
- (v: V) => R
41
- ```
42
-
43
- - **`options`** _(optional)_: Configuration options for the requestor.
44
- ```typescript
45
- interface RequestCreatorOptions<TParam> {
46
- strategy?: RequestStrategy;
47
- autoRequest?: boolean; // Only if TParam is empty array
48
- injector?: Injector; // Provide custom injector
49
- }
50
- ```
51
-
52
- ## Return Value
53
-
54
- Returns a `RequestStateStore<TParam, V, R, T>` instance configured with the provided request function and options.
55
-
56
- ## Injection Context
57
-
58
- `createRequestor` must be called within an Angular injection context OR you must provide an `injector` in the options.
59
-
60
- ### Valid Contexts
61
-
62
- ```typescript
63
- // ✅ In component/service constructor
64
- export class UserComponent {
65
- constructor() {
66
- this.userRequestor = createRequestor(
67
- (id: number) => this.http.get<User>(`/api/users/${id}`)
68
- );
69
- }
70
- }
71
-
72
- // ✅ In component/service field initializer
73
- export class UserComponent {
74
- private http = inject(HttpClient);
75
-
76
- userRequestor = createRequestor(
77
- (id: number) => this.http.get<User>(`/api/users/${id}`)
78
- );
79
- }
80
-
81
- // ✅ With custom injector
82
- export class UserComponent {
83
- private injector = inject(Injector);
84
-
85
- createUserRequestor() {
86
- return createRequestor(
87
- (id: number) => this.http.get<User>(`/api/users/${id}`),
88
- { injector: this.injector }
89
- );
90
- }
91
- }
92
-
93
- // ✅ In runInInjectionContext
94
- export class UserComponent {
95
- private injector = inject(Injector);
96
-
97
- createLater() {
98
- runInInjectionContext(this.injector, () => {
99
- return createRequestor(
100
- (id: number) => this.http.get<User>(`/api/users/${id}`)
101
- );
102
- });
103
- }
104
- }
105
- ```
106
-
107
- ### Invalid Contexts
108
-
109
- ```typescript
110
- // ❌ Outside injection context without injector
111
- function createUserRequestor() {
112
- // Error: createRequestor() must be used in an Injection Context
113
- return createRequestor(
114
- (id: number) => inject(HttpClient).get<User>(`/api/users/${id}`)
115
- );
116
- }
117
- ```
118
-
119
- ## Basic Usage
120
-
121
- ### Simple Request (No Parameters)
122
-
123
- ```typescript
124
- import { createRequestor } from 'angular-utilities';
125
- import { inject } from '@angular/core';
126
- import { HttpClient } from '@angular/common/http';
127
-
128
- export class ConfigService {
129
- private http = inject(HttpClient);
130
-
131
- // Request with no parameters
132
- configRequestor = createRequestor(
133
- () => this.http.get<AppConfig>('/api/config')
134
- );
135
-
136
- loadConfig() {
137
- this.configRequestor.request();
138
- }
139
- }
140
- ```
141
-
142
- ### Request with Single Parameter
143
-
144
- ```typescript
145
- export class UserService {
146
- private http = inject(HttpClient);
147
-
148
- userRequestor = createRequestor(
149
- (userId: number) => this.http.get<User>(`/api/users/${userId}`)
150
- );
151
-
152
- loadUser(id: number) {
153
- this.userRequestor.request(id);
154
- }
155
- }
156
- ```
157
-
158
- ### Request with Multiple Parameters
159
-
160
- ```typescript
161
- export class SearchService {
162
- private http = inject(HttpClient);
163
-
164
- searchRequestor = createRequestor(
165
- (query: string, page: number, pageSize: number) =>
166
- this.http.get<SearchResults>(
167
- `/api/search?q=${query}&page=${page}&size=${pageSize}`
168
- )
169
- );
170
-
171
- search(query: string, page: number = 1, pageSize: number = 20) {
172
- this.searchRequestor.request(query, page, pageSize);
173
- }
174
- }
175
- ```
176
-
177
- ## With Projection
178
-
179
- Projection allows you to transform the response before it's stored in state.
180
-
181
- ### Basic Projection
182
-
183
- ```typescript
184
- interface UserDTO {
185
- user_id: number;
186
- first_name: string;
187
- last_name: string;
188
- email_address: string;
189
- }
190
-
191
- interface User {
192
- id: number;
193
- name: string;
194
- email: string;
195
- }
196
-
197
- export class UserService {
198
- private http = inject(HttpClient);
199
-
200
- userRequestor = createRequestor(
201
- (id: number) => this.http.get<UserDTO>(`/api/users/${id}`),
202
- (dto: UserDTO): User => ({
203
- id: dto.user_id,
204
- name: `${dto.first_name} ${dto.last_name}`,
205
- email: dto.email_address
206
- })
207
- );
208
- }
209
- ```
210
-
211
- ### Projection with Options
212
-
213
- ```typescript
214
- userRequestor = createRequestor(
215
- (id: number) => this.http.get<UserDTO>(`/api/users/${id}`),
216
- (dto: UserDTO): User => this.transformUser(dto),
217
- { strategy: RequestStrategy.cancelPrevious }
218
- );
219
- ```
220
-
221
- ## Request Strategies
222
-
223
- ### Cancel Previous (Default)
224
-
225
- Cancels in-flight requests when a new request is made. Ideal for search/autocomplete.
226
-
227
- ```typescript
228
- const searchRequestor = createRequestor(
229
- (query: string) => this.http.get(`/api/search?q=${query}`),
230
- { strategy: RequestStrategy.cancelPrevious }
231
- );
232
- ```
233
-
234
- ### Concurrent
235
-
236
- Allows multiple requests to execute simultaneously.
237
-
238
- ```typescript
239
- const userRequestor = createRequestor(
240
- (userId: number) => this.http.get(`/api/users/${userId}`),
241
- { strategy: RequestStrategy.concurrent }
242
- );
243
-
244
- // All requests execute in parallel
245
- userRequestor.request(1);
246
- userRequestor.request(2);
247
- userRequestor.request(3);
248
- ```
249
-
250
- ### Sequential
251
-
252
- Queues requests and executes them one at a time in order.
253
-
254
- ```typescript
255
- const uploadRequestor = createRequestor(
256
- (file: File) => this.http.post('/api/upload', file),
257
- { strategy: RequestStrategy.sequential }
258
- );
259
-
260
- // Requests execute in order
261
- uploadRequestor.request(file1);
262
- uploadRequestor.request(file2); // Waits for file1
263
- uploadRequestor.request(file3); // Waits for file2
264
- ```
265
-
266
- ### Single Use
267
-
268
- Only allows one request for the lifetime of the requestor. Must call `reset()` to make another request.
269
-
270
- ```typescript
271
- const initRequestor = createRequestor(
272
- () => this.http.post('/api/initialize', {}),
273
- { strategy: RequestStrategy.singleUse }
274
- );
275
-
276
- initRequestor.request(); // OK
277
- initRequestor.request(); // Error!
278
- initRequestor.reset(); // Reset state
279
- initRequestor.request(); // OK again
280
- ```
281
-
282
- ## Auto Request
283
-
284
- Automatically execute the request when the requestor is created. Only available for requests with no parameters.
285
-
286
- ```typescript
287
- const configRequestor = createRequestor(
288
- () => this.http.get<Config>('/api/config'),
289
- { autoRequest: true }
290
- );
291
- // Request executes immediately upon creation
292
- ```
293
-
294
- ## Custom Injector
295
-
296
- Provide a custom injector when creating the requestor outside an injection context.
297
-
298
- ```typescript
299
- export class DynamicRequestService {
300
- private injector = inject(Injector);
301
-
302
- createDynamicRequestor(endpoint: string) {
303
- // Create requestor outside injection context
304
- return createRequestor(
305
- () => this.http.get(endpoint),
306
- { injector: this.injector }
307
- );
308
- }
309
- }
310
- ```
311
-
312
- ## Comparison with RequestStateFactory
313
-
314
- ### Using `createRequestor` (Recommended)
315
-
316
- ```typescript
317
- export class UserComponent {
318
- private http = inject(HttpClient);
319
-
320
- // Direct creation - cleaner and more modern
321
- userRequestor = createRequestor(
322
- (id: number) => this.http.get<User>(`/api/users/${id}`)
323
- );
324
- }
325
- ```
326
-
327
- ### Using `RequestStateFactory`
328
-
329
- ```typescript
330
- @Component({
331
- providers: [RequestStateFactory] // Must provide in component/module
332
- })
333
- export class UserComponent {
334
- private factory = inject(RequestStateFactory);
335
- private http = inject(HttpClient);
336
-
337
- // Factory method - requires provider
338
- userRequestor = this.factory.create(
339
- (id: number) => this.http.get<User>(`/api/users/${id}`)
340
- );
341
- }
342
- ```
343
-
344
- **Benefits of `createRequestor`:**
345
- - No need to provide `RequestStateFactory` in component/module
346
- - More concise and functional
347
- - Better tree-shaking
348
- - Easier to test
349
-
350
- **When to use `RequestStateFactory`:**
351
- - Need centralized lifecycle management across multiple requestors
352
- - Want to batch cleanup operations
353
- - Working with older Angular patterns
354
-
355
- ## Common Patterns
356
-
357
- ### Component with Master-Detail
358
-
359
- ```typescript
360
- @Component({
361
- selector: 'app-user-detail',
362
- template: `
363
- @if (user.$isInProgress()) {
364
- <mat-spinner />
365
- } @else if (user.$isSuccess()) {
366
- <h1>{{ user.$selectResponse()?.name }}</h1>
367
- <p>{{ user.$selectResponse()?.email }}</p>
368
- }
369
- `
370
- })
371
- export class UserDetailComponent {
372
- private http = inject(HttpClient);
373
- private route = inject(ActivatedRoute);
374
-
375
- userId = toSignal(this.route.params.pipe(map(p => +p['id'])));
376
- userIdArray = computed(() => [this.userId()]);
377
-
378
- user = createRequestor(
379
- (id: number) => this.http.get<User>(`/api/users/${id}`)
380
- ).requestWith(this.userIdArray);
381
- }
382
- ```
383
-
384
- ### Search with Debounce
385
-
386
- ```typescript
387
- @Component({
388
- selector: 'app-search',
389
- template: `
390
- <input [ngModel]="searchTerm()" (ngModelChange)="searchTerm.set($event)" />
391
-
392
- @if (results.$isSuccess()) {
393
- @for (item of results.$selectResponse(); track item.id) {
394
- <div>{{ item.name }}</div>
395
- }
396
- }
397
- `
398
- })
399
- export class SearchComponent {
400
- private http = inject(HttpClient);
401
-
402
- searchTerm = signal('');
403
-
404
- results = createRequestor(
405
- (term: string) => this.http.get<Item[]>(`/api/search?q=${term}`),
406
- { strategy: RequestStrategy.cancelPrevious }
407
- ).requestWith(
408
- toObservable(this.searchTerm).pipe(
409
- debounceTime(300),
410
- filter(term => term.length >= 3),
411
- map(term => [term])
412
- )
413
- );
414
- }
415
- ```
416
-
417
- ### Form Submission with Error Handling
418
-
419
- ```typescript
420
- @Component({
421
- selector: 'app-user-form',
422
- template: `
423
- <form (ngSubmit)="onSubmit()">
424
- <!-- form fields -->
425
- <button type="submit" [disabled]="saveUser.$isInProgress()">
426
- @if (saveUser.$isInProgress()) {
427
- Saving...
428
- } @else {
429
- Save User
430
- }
431
- </button>
432
- </form>
433
- `
434
- })
435
- export class UserFormComponent {
436
- private http = inject(HttpClient);
437
- private router = inject(Router);
438
- private snackBar = inject(MatSnackBar);
439
-
440
- saveUser = createRequestor(
441
- (user: User) => this.http.post<User>('/api/users', user)
442
- )
443
- .onSuccess((savedUser) => {
444
- this.snackBar.open('User saved successfully', 'Close', { duration: 3000 });
445
- this.router.navigate(['/users', savedUser.id]);
446
- })
447
- .onError((error) => {
448
- this.snackBar.open(`Error: ${error.message}`, 'Close', { duration: 5000 });
449
- });
450
-
451
- onSubmit() {
452
- if (this.form.valid) {
453
- this.saveUser.request(this.form.value);
454
- }
455
- }
456
- }
457
- ```
458
-
459
- ### Multiple Dependent Requests
460
-
461
- ```typescript
462
- export class UserDashboardComponent {
463
- private http = inject(HttpClient);
464
-
465
- userId = signal(1);
466
- userIdArray = computed(() => [this.userId()]);
467
-
468
- // First request
469
- user = createRequestor(
470
- (id: number) => this.http.get<User>(`/api/users/${id}`)
471
- ).requestWith(this.userIdArray);
472
-
473
- // Second request depends on first
474
- userPosts = createRequestor(
475
- (userId: number) => this.http.get<Post[]>(`/api/users/${userId}/posts`)
476
- ).requestWith(this.userIdArray);
477
-
478
- // Third request depends on first
479
- userComments = createRequestor(
480
- (userId: number) => this.http.get<Comment[]>(`/api/users/${userId}/comments`)
481
- ).requestWith(this.userIdArray);
482
- }
483
- ```
484
-
485
- ### Combining Multiple Signals
486
-
487
- ```typescript
488
- export class ReportComponent {
489
- private http = inject(HttpClient);
490
-
491
- startDate = signal(new Date());
492
- endDate = signal(new Date());
493
- reportType = signal('summary');
494
-
495
- // Combine multiple signals
496
- report = createRequestor(
497
- (start: Date, end: Date, type: string) =>
498
- this.http.get(`/api/reports?start=${start}&end=${end}&type=${type}`)
499
- ).requestOn(this.startDate, this.endDate, this.reportType);
500
- // Automatically makes a new request when any signal changes
501
- }
502
- ```
503
-
504
- ### Polling Pattern
505
-
506
- ```typescript
507
- export class StatusComponent implements OnInit {
508
- private http = inject(HttpClient);
509
-
510
- status = createRequestor(
511
- () => this.http.get<Status>('/api/status'),
512
- { strategy: RequestStrategy.sequential }
513
- );
514
-
515
- ngOnInit() {
516
- // Poll every 5 seconds
517
- interval(5000).pipe(
518
- takeUntilDestroyed()
519
- ).subscribe(() => {
520
- this.status.request();
521
- });
522
- }
523
- }
524
- ```
525
-
526
- ## Error Handling
527
-
528
- The `createRequestor` function returns a requestor that can be chained with error handlers.
529
-
530
- ```typescript
531
- const userRequestor = createRequestor(
532
- (id: number) => this.http.get<User>(`/api/users/${id}`)
533
- )
534
- .onError((error) => {
535
- console.error('Failed to load user:', error);
536
- })
537
- .useDefaultErrorHandler(); // Use global error handler if configured
538
- ```
539
-
540
- See the [Requestor Documentation](./REQUESTOR.md#error-handling) for complete error handling patterns.
541
-
542
- ## Success Handling
543
-
544
- Chain success handlers for side effects after successful requests.
545
-
546
- ```typescript
547
- const deleteUserRequestor = createRequestor(
548
- (id: number) => this.http.delete(`/api/users/${id}`)
549
- )
550
- .onSuccess(() => {
551
- this.showSuccessMessage('User deleted');
552
- this.refreshUserList();
553
- });
554
- ```
555
-
556
- See the [Requestor Documentation](./REQUESTOR.md#success-handling) for complete success handling patterns.
557
-
558
- ## Testing
559
-
560
- ### Testing Components with Requestors
561
-
562
- ```typescript
563
- describe('UserComponent', () => {
564
- let component: UserComponent;
565
- let httpMock: HttpTestingController;
566
-
567
- beforeEach(() => {
568
- TestBed.configureTestingModule({
569
- imports: [HttpClientTestingModule],
570
- declarations: [UserComponent]
571
- });
572
-
573
- component = TestBed.createComponent(UserComponent).componentInstance;
574
- httpMock = TestBed.inject(HttpTestingController);
575
- });
576
-
577
- it('should load user', () => {
578
- const mockUser: User = { id: 1, name: 'John', email: 'john@test.com' };
579
-
580
- component.userRequestor.request(1);
581
-
582
- const req = httpMock.expectOne('/api/users/1');
583
- expect(req.request.method).toBe('GET');
584
- req.flush(mockUser);
585
-
586
- expect(component.userRequestor.$isSuccess()).toBe(true);
587
- expect(component.userRequestor.$selectResponse()).toEqual(mockUser);
588
- });
589
-
590
- it('should handle error', () => {
591
- component.userRequestor.request(999);
592
-
593
- const req = httpMock.expectOne('/api/users/999');
594
- req.error(new ProgressEvent('error'), { status: 404, statusText: 'Not Found' });
595
-
596
- expect(component.userRequestor.$isError()).toBe(true);
597
- });
598
-
599
- afterEach(() => {
600
- httpMock.verify();
601
- });
602
- });
603
- ```
604
-
605
- ### Mocking Requestors in Tests
606
-
607
- ```typescript
608
- describe('UserDashboardComponent', () => {
609
- let component: UserDashboardComponent;
610
-
611
- beforeEach(() => {
612
- // Create a mock requestor
613
- const mockRequestor = {
614
- request: jasmine.createSpy('request'),
615
- $isSuccess: signal(true),
616
- $selectResponse: signal({ id: 1, name: 'Test User' }),
617
- $isInProgress: signal(false),
618
- $isError: signal(false)
619
- } as any;
620
-
621
- TestBed.configureTestingModule({
622
- declarations: [UserDashboardComponent],
623
- providers: [
624
- { provide: UserService, useValue: { userRequestor: mockRequestor } }
625
- ]
626
- });
627
-
628
- component = TestBed.createComponent(UserDashboardComponent).componentInstance;
629
- });
630
-
631
- it('should display user data', () => {
632
- expect(component.userService.userRequestor.$selectResponse()?.name)
633
- .toBe('Test User');
634
- });
635
- });
636
- ```
637
-
638
- ## Best Practices
639
-
640
- ### Using `createRequestor` over `RequestStateFactory`**: It's more modern and requires less boilerplate.
641
-
642
- 2. **Create requestors as class properties**: Define them at the class level for easy access.
643
- ```typescript
644
- export class UserComponent {
645
- userRequestor = createRequestor(...);
646
- }
647
- ```
648
-
649
- 3. **Remember `requestWith` takes an array**: When using `requestWith`, ensure your observable/signal emits an array of parameters.
650
-
651
- 3. **Choose appropriate strategies**: Match the strategy to your use case (cancelPrevious for search, concurrent for independent operations).
652
-
653
- 4. **Use projection for transformation**: Keep transformation logic in the requestor rather than in components.
654
-
655
- 5. **Chain handlers fluently**: Take advantage of method chaining for clean code.
656
-
657
- 6. **Provide custom injector when needed**: If creating outside injection context, always provide an injector.
658
-
659
- 7. **Type your responses**: Always specify generic types for compile-time safety.
660
-
661
- 8. **Use signals for reactivity**: Prefer signal-based state access (`$selectResponse()`) over observables in templates.
662
-
663
- ## See Also
664
-
665
- - [Requestor (RequestStateStore) Documentation](./REQUESTOR.md)
666
- - [RequestStateFactory Documentation](./REQUEST-STATE-FACTORY.md)
667
- - [Request State Types](./REQUEST-STATE-TYPES.md)