@hichchi/ngx-utils 0.0.1-alpha.3 → 0.0.1-alpha.5

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.
package/README.md CHANGED
@@ -194,8 +194,16 @@ Complete technical reference for all classes, interfaces, methods, and types in
194
194
  - [Functions](#functions)
195
195
  - [apiUrlInterceptor()](#apiurlinterceptor)
196
196
  - [createFormData()](#createformdata)
197
+ - [errorResponseInterceptor()](#errorresponseinterceptor)
198
+ - [getClosestScrollableElement()](#getclosestscrollableelement)
199
+ - [isElementInView()](#iselementinview)
200
+ - [isScrollable()](#isscrollable)
201
+ - [isSuccessResponse()](#issuccessresponse)
197
202
  - [markFormDirty()](#markformdirty)
198
203
  - [replaceNulls()](#replacenulls)
204
+ - [saveAsFile()](#saveasfile)
205
+ - [skipNotify()](#skipnotify)
206
+ - [skipNotifyContext()](#skipnotifycontext)
199
207
  - [validatedFormData()](#validatedformdata)
200
208
  - [Interfaces](#interfaces)
201
209
  - [DataFormGroup\<T>](#dataformgroupt)
@@ -215,7 +223,7 @@ Complete technical reference for all classes, interfaces, methods, and types in
215
223
 
216
224
  ### `abstract` HichchiHttpService
217
225
 
218
- Defined in: [libs/ngx-utils/src/lib/services/hichchi-http.service.ts:3](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/services/hichchi-http.service.ts#L3)
226
+ Defined in: [libs/ngx-utils/src/lib/services/hichchi-http.service.ts:3](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/services/hichchi-http.service.ts#L3)
219
227
 
220
228
  #### Constructors
221
229
 
@@ -225,7 +233,7 @@ Defined in: [libs/ngx-utils/src/lib/services/hichchi-http.service.ts:3](https://
225
233
  protected new HichchiHttpService(http): HichchiHttpService;
226
234
  ```
227
235
 
228
- Defined in: [libs/ngx-utils/src/lib/services/hichchi-http.service.ts:4](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/services/hichchi-http.service.ts#L4)
236
+ Defined in: [libs/ngx-utils/src/lib/services/hichchi-http.service.ts:4](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/services/hichchi-http.service.ts#L4)
229
237
 
230
238
  ###### Parameters
231
239
 
@@ -264,7 +272,7 @@ Defined in: [libs/ngx-utils/src/lib/services/hichchi-http.service.ts:4](https://
264
272
  function apiUrlInterceptor(apiBase): HttpInterceptorFn;
265
273
  ```
266
274
 
267
- Defined in: [libs/ngx-utils/src/lib/interceptors/api-url-interceptor.ts:98](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/interceptors/api-url-interceptor.ts#L98)
275
+ Defined in: [libs/ngx-utils/src/lib/interceptors/api-url-interceptor.ts:98](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/interceptors/api-url-interceptor.ts#L98)
268
276
 
269
277
  Creates an HTTP interceptor that automatically prepends a base API URL to relative requests
270
278
 
@@ -396,7 +404,7 @@ export class AppModule {}
396
404
  function createFormData<T>(data): FormData;
397
405
  ```
398
406
 
399
- Defined in: [libs/ngx-utils/src/lib/form/form.utils.ts:404](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/form/form.utils.ts#L404)
407
+ Defined in: [libs/ngx-utils/src/lib/form/form.utils.ts:404](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/form/form.utils.ts#L404)
400
408
 
401
409
  Creates a FormData object from a plain JavaScript object
402
410
 
@@ -576,13 +584,683 @@ const formData = createFormData(uploadRequest);
576
584
 
577
585
  ---
578
586
 
587
+ ### errorResponseInterceptor()
588
+
589
+ ```ts
590
+ function errorResponseInterceptor(
591
+ providerWithNotify,
592
+ providerWithSignOut,
593
+ ): HttpInterceptorFn;
594
+ ```
595
+
596
+ Defined in: [libs/ngx-utils/src/lib/interceptors/error.interceptor.ts:140](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/interceptors/error.interceptor.ts#L140)
597
+
598
+ Creates an HTTP error response interceptor for Angular applications
599
+
600
+ This function creates an HTTP interceptor that handles error responses from API calls.
601
+ It provides centralized error handling with support for authentication error detection,
602
+ automatic user sign-out on unauthorized access, and configurable error notifications.
603
+ The interceptor integrates with notification services and authentication services to
604
+ provide a seamless error handling experience.
605
+
606
+ The interceptor distinguishes between different types of errors and handles them
607
+ appropriately. It can detect known authentication errors, handle unauthorized access
608
+ by automatically signing out users, and show error notifications based on request
609
+ context configuration.
610
+
611
+ Key features:
612
+
613
+ - Centralized HTTP error handling for all API requests
614
+ - Authentication error detection and handling
615
+ - Automatic user sign-out on unauthorized access
616
+ - Configurable error notifications per request
617
+ - Integration with notification and authentication services
618
+ - Support for both client-side and server-side errors
619
+ - Context-aware error handling based on request configuration
620
+
621
+ #### Parameters
622
+
623
+ <table>
624
+ <thead>
625
+ <tr>
626
+ <th>Parameter</th>
627
+ <th>Type</th>
628
+ <th>Description</th>
629
+ </tr>
630
+ </thead>
631
+ <tbody>
632
+ <tr>
633
+ <td>
634
+
635
+ `providerWithNotify`
636
+
637
+ </td>
638
+ <td>
639
+
640
+ `Type`<{ `error`: (`message`) => `void`; }>
641
+
642
+ </td>
643
+ <td>
644
+
645
+ Service provider type that implements error notification functionality
646
+
647
+ </td>
648
+ </tr>
649
+ <tr>
650
+ <td>
651
+
652
+ `providerWithSignOut`
653
+
654
+ </td>
655
+ <td>
656
+
657
+ `Type`<{ `signOut`: () => `void`; }>
658
+
659
+ </td>
660
+ <td>
661
+
662
+ Service provider type that implements user sign-out functionality
663
+
664
+ </td>
665
+ </tr>
666
+ </tbody>
667
+ </table>
668
+
669
+ #### Returns
670
+
671
+ `HttpInterceptorFn`
672
+
673
+ HttpInterceptorFn that can be used in Angular HTTP interceptor configuration
674
+
675
+ #### Examples
676
+
677
+ ```typescript
678
+ // Basic usage in app configuration
679
+ import { provideHttpClient, withInterceptors } from "@angular/common/http";
680
+ import { NotificationService } from "./services/notification.service";
681
+ import { AuthService } from "./services/auth.service";
682
+
683
+ export const appConfig: ApplicationConfig = {
684
+ providers: [
685
+ provideHttpClient(
686
+ withInterceptors([
687
+ errorResponseInterceptor(NotificationService, AuthService),
688
+ ]),
689
+ ),
690
+ ],
691
+ };
692
+ ```
693
+
694
+ ```typescript
695
+ // Using with custom notification and auth services
696
+ import { ToastService } from "./services/toast.service";
697
+ import { UserAuthService } from "./services/user-auth.service";
698
+
699
+ const errorInterceptor = errorResponseInterceptor(
700
+ ToastService,
701
+ UserAuthService,
702
+ );
703
+
704
+ export const appConfig: ApplicationConfig = {
705
+ providers: [provideHttpClient(withInterceptors([errorInterceptor]))],
706
+ };
707
+ ```
708
+
709
+ ```typescript
710
+ // Service implementations that work with the interceptor
711
+ @Injectable()
712
+ export class NotificationService {
713
+ error(message: string): void {
714
+ // Show error notification to user
715
+ this.toastr.error(message);
716
+ }
717
+ }
718
+
719
+ @Injectable()
720
+ export class AuthService {
721
+ signOut(): void {
722
+ // Clear user session and redirect to login
723
+ this.clearTokens();
724
+ this.router.navigate(["/login"]);
725
+ }
726
+ }
727
+ ```
728
+
729
+ ```typescript
730
+ // Making HTTP requests with error notification control
731
+ import { HttpClient } from "@angular/common/http";
732
+ import { skipNotifyContext } from "@hichchi/ngx-utils";
733
+
734
+ @Injectable()
735
+ export class DataService {
736
+ constructor(private http: HttpClient) {}
737
+
738
+ // Request with error notifications enabled (default)
739
+ getData() {
740
+ return this.http.get("/api/data");
741
+ }
742
+
743
+ // Request with error notifications disabled
744
+ getDataSilently() {
745
+ return this.http.get("/api/data", skipNotifyContext(true));
746
+ }
747
+ }
748
+ ```
749
+
750
+ ```typescript
751
+ // Advanced usage with multiple interceptors
752
+ import { AuthInterceptor } from "./interceptors/auth.interceptor";
753
+ import { LoadingInterceptor } from "./interceptors/loading.interceptor";
754
+
755
+ export const appConfig: ApplicationConfig = {
756
+ providers: [
757
+ provideHttpClient(
758
+ withInterceptors([
759
+ AuthInterceptor,
760
+ LoadingInterceptor,
761
+ errorResponseInterceptor(NotificationService, AuthService),
762
+ ]),
763
+ ),
764
+ ],
765
+ };
766
+ ```
767
+
768
+ #### See
769
+
770
+ - HttpInterceptorFn Angular HTTP interceptor function type
771
+ - [HttpError](#httperror) Interface for HTTP error objects
772
+ - NOTIFY_ERRORS Token for controlling error notification context
773
+ - AuthErrorResponseCode Enum of known authentication error codes
774
+ - HttpClientErrorStatus Enum of HTTP client error status codes
775
+
776
+ ---
777
+
778
+ ### getClosestScrollableElement()
779
+
780
+ ```ts
781
+ function getClosestScrollableElement(el): null | HTMLElement;
782
+ ```
783
+
784
+ Defined in: [libs/ngx-utils/src/lib/utils/html.utils.ts:257](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/utils/html.utils.ts#L257)
785
+
786
+ Finds the closest scrollable ancestor element in the DOM tree
787
+
788
+ This utility function traverses up the DOM tree from a given element to find the
789
+ nearest ancestor that is scrollable. It uses the isScrollable function to determine
790
+ scrollability and returns the first scrollable parent element found.
791
+
792
+ This is useful for implementing scroll-related functionality that needs to work
793
+ with the appropriate scrollable container, such as:
794
+
795
+ - Implementing custom scroll behaviors
796
+ - Adding scroll event listeners to the correct container
797
+ - Calculating scroll positions relative to the scrollable parent
798
+ - Implementing scroll-to-element functionality
799
+
800
+ #### Parameters
801
+
802
+ <table>
803
+ <thead>
804
+ <tr>
805
+ <th>Parameter</th>
806
+ <th>Type</th>
807
+ <th>Description</th>
808
+ </tr>
809
+ </thead>
810
+ <tbody>
811
+ <tr>
812
+ <td>
813
+
814
+ `el`
815
+
816
+ </td>
817
+ <td>
818
+
819
+ `HTMLElement`
820
+
821
+ </td>
822
+ <td>
823
+
824
+ The starting HTML element to search from
825
+
826
+ </td>
827
+ </tr>
828
+ </tbody>
829
+ </table>
830
+
831
+ #### Returns
832
+
833
+ `null` | `HTMLElement`
834
+
835
+ The closest scrollable ancestor element, or null if none is found
836
+
837
+ #### Examples
838
+
839
+ ```typescript
840
+ // Find the scrollable container for a specific element
841
+ const targetElement = document.querySelector(".target-element");
842
+ if (targetElement) {
843
+ const scrollableParent = getClosestScrollableElement(targetElement);
844
+
845
+ if (scrollableParent) {
846
+ console.log("Found scrollable parent:", scrollableParent);
847
+ // Add scroll event listener to the correct container
848
+ scrollableParent.addEventListener("scroll", handleScroll);
849
+ } else {
850
+ console.log("No scrollable parent found");
851
+ }
852
+ }
853
+ ```
854
+
855
+ ```typescript
856
+ // Implement scroll-to-element functionality
857
+ function scrollToElement(
858
+ element: HTMLElement,
859
+ behavior: ScrollBehavior = "smooth",
860
+ ) {
861
+ const scrollableContainer = getClosestScrollableElement(element);
862
+
863
+ if (scrollableContainer) {
864
+ // Calculate the position relative to the scrollable container
865
+ const containerRect = scrollableContainer.getBoundingClientRect();
866
+ const elementRect = element.getBoundingClientRect();
867
+ const relativeTop =
868
+ elementRect.top - containerRect.top + scrollableContainer.scrollTop;
869
+
870
+ scrollableContainer.scrollTo({
871
+ top: relativeTop,
872
+ behavior,
873
+ });
874
+ } else {
875
+ // Fallback to window scroll
876
+ element.scrollIntoView({ behavior });
877
+ }
878
+ }
879
+ ```
880
+
881
+ ```typescript
882
+ // Use in Angular directive for scroll-based functionality
883
+ @Directive({
884
+ selector: "[appScrollSpy]",
885
+ })
886
+ export class ScrollSpyDirective implements OnInit, OnDestroy {
887
+ private scrollContainer: HTMLElement | null = null;
888
+ private scrollListener?: () => void;
889
+
890
+ constructor(private elementRef: ElementRef<HTMLElement>) {}
891
+
892
+ ngOnInit() {
893
+ this.scrollContainer = getClosestScrollableElement(
894
+ this.elementRef.nativeElement,
895
+ );
896
+
897
+ if (this.scrollContainer) {
898
+ this.scrollListener = () => this.onScroll();
899
+ this.scrollContainer.addEventListener("scroll", this.scrollListener);
900
+ }
901
+ }
902
+
903
+ ngOnDestroy() {
904
+ if (this.scrollContainer && this.scrollListener) {
905
+ this.scrollContainer.removeEventListener("scroll", this.scrollListener);
906
+ }
907
+ }
908
+
909
+ private onScroll() {
910
+ // Implement scroll spy logic
911
+ if (
912
+ this.scrollContainer &&
913
+ isElementInView(this.elementRef.nativeElement, this.scrollContainer)
914
+ ) {
915
+ // Element is in view
916
+ console.log("Element is visible in scroll container");
917
+ }
918
+ }
919
+ }
920
+ ```
921
+
922
+ #### See
923
+
924
+ - [isScrollable](#isscrollable) Function used internally to determine scrollability
925
+ - [isElementInView](#iselementinview) Function that can be used with the returned scrollable element
926
+ - HTMLElement.parentElement DOM property used for tree traversal
927
+
928
+ ---
929
+
930
+ ### isElementInView()
931
+
932
+ ```ts
933
+ function isElementInView(el, container, threshold): boolean;
934
+ ```
935
+
936
+ Defined in: [libs/ngx-utils/src/lib/utils/html.utils.ts:153](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/utils/html.utils.ts#L153)
937
+
938
+ Determines if an element is fully visible within a container element
939
+
940
+ This utility function checks whether a target element is completely visible within
941
+ the bounds of a container element. It compares the bounding rectangles of both
942
+ elements and optionally applies a threshold for more flexible visibility detection.
943
+
944
+ This is particularly useful for implementing features like:
945
+
946
+ - Lazy loading of content when elements come into view
947
+ - Scroll-based animations and transitions
948
+ - Virtual scrolling implementations
949
+ - Accessibility features that track visible content
950
+
951
+ #### Parameters
952
+
953
+ <table>
954
+ <thead>
955
+ <tr>
956
+ <th>Parameter</th>
957
+ <th>Type</th>
958
+ <th>Default value</th>
959
+ <th>Description</th>
960
+ </tr>
961
+ </thead>
962
+ <tbody>
963
+ <tr>
964
+ <td>
965
+
966
+ `el`
967
+
968
+ </td>
969
+ <td>
970
+
971
+ `HTMLElement`
972
+
973
+ </td>
974
+ <td>
975
+
976
+ `undefined`
977
+
978
+ </td>
979
+ <td>
980
+
981
+ The target element to check for visibility
982
+
983
+ </td>
984
+ </tr>
985
+ <tr>
986
+ <td>
987
+
988
+ `container`
989
+
990
+ </td>
991
+ <td>
992
+
993
+ `HTMLElement`
994
+
995
+ </td>
996
+ <td>
997
+
998
+ `undefined`
999
+
1000
+ </td>
1001
+ <td>
1002
+
1003
+ The container element that defines the visible area
1004
+
1005
+ </td>
1006
+ </tr>
1007
+ <tr>
1008
+ <td>
1009
+
1010
+ `threshold`
1011
+
1012
+ </td>
1013
+ <td>
1014
+
1015
+ `number`
1016
+
1017
+ </td>
1018
+ <td>
1019
+
1020
+ `0`
1021
+
1022
+ </td>
1023
+ <td>
1024
+
1025
+ Optional threshold in pixels for more flexible visibility detection (default: 0)
1026
+
1027
+ </td>
1028
+ </tr>
1029
+ </tbody>
1030
+ </table>
1031
+
1032
+ #### Returns
1033
+
1034
+ `boolean`
1035
+
1036
+ True if the element is fully visible within the container, false otherwise
1037
+
1038
+ #### Examples
1039
+
1040
+ ```typescript
1041
+ // Check if a list item is visible in a scrollable container
1042
+ const listItem = document.querySelector(".list-item");
1043
+ const scrollContainer = document.querySelector(".scroll-container");
1044
+
1045
+ if (listItem && scrollContainer && isElementInView(listItem, scrollContainer)) {
1046
+ console.log("List item is fully visible");
1047
+ // Trigger animations or load additional content
1048
+ }
1049
+ ```
1050
+
1051
+ ```typescript
1052
+ // Use with a threshold for partial visibility detection
1053
+ const image = document.querySelector(".lazy-image");
1054
+ const viewport = document.querySelector(".viewport");
1055
+
1056
+ // Check if image is visible with 50px threshold
1057
+ if (image && viewport && isElementInView(image, viewport, 50)) {
1058
+ // Load the image when it's within 50px of being visible
1059
+ loadImage(image);
1060
+ }
1061
+ ```
1062
+
1063
+ ```typescript
1064
+ // Implement scroll-based visibility tracking in Angular
1065
+ @Component({
1066
+ selector: "app-scroll-tracker",
1067
+ template: `
1068
+ <div #container class="scroll-container" (scroll)="onScroll()">
1069
+ <div
1070
+ #item
1071
+ *ngFor="let item of items; trackBy: trackByFn"
1072
+ class="scroll-item"
1073
+ [class.visible]="item.isVisible"
1074
+ >
1075
+ {{ item.content }}
1076
+ </div>
1077
+ </div>
1078
+ `,
1079
+ })
1080
+ export class ScrollTrackerComponent {
1081
+ @ViewChild("container") container!: ElementRef<HTMLElement>;
1082
+ @ViewChildren("item") itemElements!: QueryList<ElementRef<HTMLElement>>;
1083
+
1084
+ items = [
1085
+ { id: 1, content: "Item 1", isVisible: false },
1086
+ { id: 2, content: "Item 2", isVisible: false },
1087
+ // ... more items
1088
+ ];
1089
+
1090
+ onScroll() {
1091
+ this.itemElements.forEach((itemRef, index) => {
1092
+ this.items[index].isVisible = isElementInView(
1093
+ itemRef.nativeElement,
1094
+ this.container.nativeElement,
1095
+ 20, // 20px threshold
1096
+ );
1097
+ });
1098
+ }
1099
+ }
1100
+ ```
1101
+
1102
+ #### See
1103
+
1104
+ - [isScrollable](#isscrollable) Function to check if an element is scrollable
1105
+ - [getClosestScrollableElement](#getclosestscrollableelement) Function to find the nearest scrollable ancestor
1106
+ - getBoundingClientRect DOM method used internally for position calculation
1107
+
1108
+ ---
1109
+
1110
+ ### isScrollable()
1111
+
1112
+ ```ts
1113
+ function isScrollable(el): boolean;
1114
+ ```
1115
+
1116
+ Defined in: [libs/ngx-utils/src/lib/utils/html.utils.ts:64](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/utils/html.utils.ts#L64)
1117
+
1118
+ Determines if an HTML element is scrollable
1119
+
1120
+ This utility function checks whether an HTML element has scrollable content by examining
1121
+ its computed CSS overflow-y property and comparing its scroll height to its client height.
1122
+ An element is considered scrollable if it has overflow set to 'scroll' or 'auto' and
1123
+ its content exceeds the visible area.
1124
+
1125
+ This is useful for implementing scroll-related functionality, such as infinite scrolling,
1126
+ scroll position tracking, or determining whether scroll indicators should be shown.
1127
+
1128
+ #### Parameters
1129
+
1130
+ <table>
1131
+ <thead>
1132
+ <tr>
1133
+ <th>Parameter</th>
1134
+ <th>Type</th>
1135
+ <th>Description</th>
1136
+ </tr>
1137
+ </thead>
1138
+ <tbody>
1139
+ <tr>
1140
+ <td>
1141
+
1142
+ `el`
1143
+
1144
+ </td>
1145
+ <td>
1146
+
1147
+ `HTMLElement`
1148
+
1149
+ </td>
1150
+ <td>
1151
+
1152
+ The HTML element to check for scrollability
1153
+
1154
+ </td>
1155
+ </tr>
1156
+ </tbody>
1157
+ </table>
1158
+
1159
+ #### Returns
1160
+
1161
+ `boolean`
1162
+
1163
+ True if the element is scrollable, false otherwise
1164
+
1165
+ #### Examples
1166
+
1167
+ ```typescript
1168
+ // Check if a container element is scrollable
1169
+ const container = document.getElementById("content-container");
1170
+ if (container && isScrollable(container)) {
1171
+ console.log("Container has scrollable content");
1172
+ // Add scroll event listeners or show scroll indicators
1173
+ }
1174
+ ```
1175
+
1176
+ ```typescript
1177
+ // Use in a component to conditionally show scroll indicators
1178
+ @Component({
1179
+ selector: "app-scrollable-content",
1180
+ template: `
1181
+ <div #contentContainer class="content">
1182
+ <!-- content -->
1183
+ </div>
1184
+ <div *ngIf="showScrollIndicator" class="scroll-indicator">
1185
+ Scroll for more content
1186
+ </div>
1187
+ `,
1188
+ })
1189
+ export class ScrollableContentComponent implements AfterViewInit {
1190
+ @ViewChild("contentContainer") contentContainer!: ElementRef<HTMLElement>;
1191
+ showScrollIndicator = false;
1192
+
1193
+ ngAfterViewInit() {
1194
+ this.showScrollIndicator = isScrollable(
1195
+ this.contentContainer.nativeElement,
1196
+ );
1197
+ }
1198
+ }
1199
+ ```
1200
+
1201
+ ```typescript
1202
+ // Check multiple elements for scrollability
1203
+ const elements = document.querySelectorAll(".potential-scroll-container");
1204
+ const scrollableElements = Array.from(elements).filter((el) =>
1205
+ isScrollable(el as HTMLElement),
1206
+ );
1207
+
1208
+ console.log(`Found ${scrollableElements.length} scrollable elements`);
1209
+ ```
1210
+
1211
+ #### See
1212
+
1213
+ - [getClosestScrollableElement](#getclosestscrollableelement) Function to find the nearest scrollable ancestor
1214
+ - [isElementInView](#iselementinview) Function to check if an element is visible within a container
1215
+
1216
+ ---
1217
+
1218
+ ### isSuccessResponse()
1219
+
1220
+ ```ts
1221
+ function isSuccessResponse(body): body is SuccessResponse;
1222
+ ```
1223
+
1224
+ Defined in: [libs/ngx-utils/src/lib/utils/http.utils.ts:17](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/utils/http.utils.ts#L17)
1225
+
1226
+ #### Parameters
1227
+
1228
+ <table>
1229
+ <thead>
1230
+ <tr>
1231
+ <th>Parameter</th>
1232
+ <th>Type</th>
1233
+ </tr>
1234
+ </thead>
1235
+ <tbody>
1236
+ <tr>
1237
+ <td>
1238
+
1239
+ `body`
1240
+
1241
+ </td>
1242
+ <td>
1243
+
1244
+ `unknown`
1245
+
1246
+ </td>
1247
+ </tr>
1248
+ </tbody>
1249
+ </table>
1250
+
1251
+ #### Returns
1252
+
1253
+ `body is SuccessResponse`
1254
+
1255
+ ---
1256
+
579
1257
  ### markFormDirty()
580
1258
 
581
1259
  ```ts
582
1260
  function markFormDirty(form): void;
583
1261
  ```
584
1262
 
585
- Defined in: [libs/ngx-utils/src/lib/form/form.utils.ts:75](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/form/form.utils.ts#L75)
1263
+ Defined in: [libs/ngx-utils/src/lib/form/form.utils.ts:75](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/form/form.utils.ts#L75)
586
1264
 
587
1265
  Recursively marks invalid form controls as dirty and touched
588
1266
 
@@ -696,7 +1374,7 @@ export class DynamicFormComponent {
696
1374
  function replaceNulls<T>(obj): { [K in string | number | symbol]?: T[K] };
697
1375
  ```
698
1376
 
699
- Defined in: [libs/ngx-utils/src/lib/form/form.utils.ts:166](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/form/form.utils.ts#L166)
1377
+ Defined in: [libs/ngx-utils/src/lib/form/form.utils.ts:166](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/form/form.utils.ts#L166)
700
1378
 
701
1379
  Removes null values from an object by deleting properties with null values
702
1380
 
@@ -824,6 +1502,218 @@ const result = replaceNulls(data);
824
1502
 
825
1503
  ---
826
1504
 
1505
+ ### saveAsFile()
1506
+
1507
+ ```ts
1508
+ function saveAsFile(blob, filename): void;
1509
+ ```
1510
+
1511
+ Defined in: [libs/ngx-utils/src/lib/utils/file.utils.ts:36](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/utils/file.utils.ts#L36)
1512
+
1513
+ Save a Blob as a file by triggering a download in the browser.
1514
+ This function creates a temporary download link and triggers a click event to download the file.
1515
+
1516
+ #### Parameters
1517
+
1518
+ <table>
1519
+ <thead>
1520
+ <tr>
1521
+ <th>Parameter</th>
1522
+ <th>Type</th>
1523
+ <th>Description</th>
1524
+ </tr>
1525
+ </thead>
1526
+ <tbody>
1527
+ <tr>
1528
+ <td>
1529
+
1530
+ `blob`
1531
+
1532
+ </td>
1533
+ <td>
1534
+
1535
+ `Blob`
1536
+
1537
+ </td>
1538
+ <td>
1539
+
1540
+ Blob to save.
1541
+
1542
+ </td>
1543
+ </tr>
1544
+ <tr>
1545
+ <td>
1546
+
1547
+ `filename`
1548
+
1549
+ </td>
1550
+ <td>
1551
+
1552
+ `string`
1553
+
1554
+ </td>
1555
+ <td>
1556
+
1557
+ File name with extension.
1558
+
1559
+ </td>
1560
+ </tr>
1561
+ </tbody>
1562
+ </table>
1563
+
1564
+ #### Returns
1565
+
1566
+ `void`
1567
+
1568
+ #### Throws
1569
+
1570
+ Throws an error if used in a Node.js environment.
1571
+
1572
+ #### Examples
1573
+
1574
+ ```TypeScript
1575
+ // Save a text file
1576
+ const textBlob = new Blob(['Hello, World!'], { type: 'text/plain' });
1577
+ saveAsFile(textBlob, 'hello.txt');
1578
+ ```
1579
+
1580
+ ```TypeScript
1581
+ // Save a JSON file
1582
+ const data = { name: 'John', age: 30 };
1583
+ const jsonBlob = new Blob([JSON.stringify(data)], { type: 'application/json' });
1584
+ saveAsFile(jsonBlob, 'user.json');
1585
+ ```
1586
+
1587
+ ```TypeScript
1588
+ // Save a file from an API response
1589
+ fetch('https://example.com/api/document')
1590
+ .then(response => response.blob())
1591
+ .then(blob => {
1592
+ saveAsFile(blob, 'document.pdf');
1593
+ });
1594
+ ```
1595
+
1596
+ ---
1597
+
1598
+ ### skipNotify()
1599
+
1600
+ ```ts
1601
+ function skipNotify(value): HttpContext;
1602
+ ```
1603
+
1604
+ Defined in: [libs/ngx-utils/src/lib/utils/http.utils.ts:9](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/utils/http.utils.ts#L9)
1605
+
1606
+ #### Parameters
1607
+
1608
+ <table>
1609
+ <thead>
1610
+ <tr>
1611
+ <th>Parameter</th>
1612
+ <th>Type</th>
1613
+ <th>Default value</th>
1614
+ </tr>
1615
+ </thead>
1616
+ <tbody>
1617
+ <tr>
1618
+ <td>
1619
+
1620
+ `value`
1621
+
1622
+ </td>
1623
+ <td>
1624
+
1625
+ `boolean`
1626
+
1627
+ </td>
1628
+ <td>
1629
+
1630
+ `false`
1631
+
1632
+ </td>
1633
+ </tr>
1634
+ </tbody>
1635
+ </table>
1636
+
1637
+ #### Returns
1638
+
1639
+ `HttpContext`
1640
+
1641
+ ---
1642
+
1643
+ ### skipNotifyContext()
1644
+
1645
+ ```ts
1646
+ function skipNotifyContext(value): object;
1647
+ ```
1648
+
1649
+ Defined in: [libs/ngx-utils/src/lib/utils/http.utils.ts:13](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/utils/http.utils.ts#L13)
1650
+
1651
+ #### Parameters
1652
+
1653
+ <table>
1654
+ <thead>
1655
+ <tr>
1656
+ <th>Parameter</th>
1657
+ <th>Type</th>
1658
+ <th>Default value</th>
1659
+ </tr>
1660
+ </thead>
1661
+ <tbody>
1662
+ <tr>
1663
+ <td>
1664
+
1665
+ `value`
1666
+
1667
+ </td>
1668
+ <td>
1669
+
1670
+ `boolean`
1671
+
1672
+ </td>
1673
+ <td>
1674
+
1675
+ `false`
1676
+
1677
+ </td>
1678
+ </tr>
1679
+ </tbody>
1680
+ </table>
1681
+
1682
+ #### Returns
1683
+
1684
+ `object`
1685
+
1686
+ <table>
1687
+ <thead>
1688
+ <tr>
1689
+ <th>Name</th>
1690
+ <th>Type</th>
1691
+ <th>Defined in</th>
1692
+ </tr>
1693
+ </thead>
1694
+ <tbody>
1695
+ <tr>
1696
+ <td>
1697
+
1698
+ `context`
1699
+
1700
+ </td>
1701
+ <td>
1702
+
1703
+ `HttpContext`
1704
+
1705
+ </td>
1706
+ <td>
1707
+
1708
+ [libs/ngx-utils/src/lib/utils/http.utils.ts:13](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/utils/http.utils.ts#L13)
1709
+
1710
+ </td>
1711
+ </tr>
1712
+ </tbody>
1713
+ </table>
1714
+
1715
+ ---
1716
+
827
1717
  ### validatedFormData()
828
1718
 
829
1719
  ```ts
@@ -832,7 +1722,7 @@ function validatedFormData<T>(
832
1722
  ): null | { [K in string | number | symbol]: T[K] };
833
1723
  ```
834
1724
 
835
- Defined in: [libs/ngx-utils/src/lib/form/form.utils.ts:278](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/form/form.utils.ts#L278)
1725
+ Defined in: [libs/ngx-utils/src/lib/form/form.utils.ts:278](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/form/form.utils.ts#L278)
836
1726
 
837
1727
  Validates a form and returns clean data if valid, or null if invalid
838
1728
 
@@ -999,7 +1889,7 @@ if (formData) {
999
1889
 
1000
1890
  ### DataFormGroup\<T>
1001
1891
 
1002
- Defined in: [libs/ngx-utils/src/lib/form/form.interfaces.ts:254](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/form/form.interfaces.ts#L254)
1892
+ Defined in: [libs/ngx-utils/src/lib/form/form.interfaces.ts:254](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/form/form.interfaces.ts#L254)
1003
1893
 
1004
1894
  Interface for a type-safe Angular reactive form group
1005
1895
 
@@ -5148,7 +6038,7 @@ UntypedFormGroup.controls;
5148
6038
  </td>
5149
6039
  <td>
5150
6040
 
5151
- [libs/ngx-utils/src/lib/form/form.interfaces.ts:255](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/form/form.interfaces.ts#L255)
6041
+ [libs/ngx-utils/src/lib/form/form.interfaces.ts:255](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/form/form.interfaces.ts#L255)
5152
6042
 
5153
6043
  </td>
5154
6044
  </tr>
@@ -5328,7 +6218,7 @@ UntypedFormGroup.value;
5328
6218
  </td>
5329
6219
  <td>
5330
6220
 
5331
- [libs/ngx-utils/src/lib/form/form.interfaces.ts:256](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/form/form.interfaces.ts#L256)
6221
+ [libs/ngx-utils/src/lib/form/form.interfaces.ts:256](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/form/form.interfaces.ts#L256)
5332
6222
 
5333
6223
  </td>
5334
6224
  </tr>
@@ -5388,7 +6278,7 @@ node_modules/@angular/forms/index.d.ts:210
5388
6278
 
5389
6279
  ### HttpError
5390
6280
 
5391
- Defined in: [libs/ngx-utils/src/lib/interfaces/http-error.interface.ts:121](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/interfaces/http-error.interface.ts#L121)
6281
+ Defined in: [libs/ngx-utils/src/lib/interfaces/http-error.interface.ts:121](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/interfaces/http-error.interface.ts#L121)
5392
6282
 
5393
6283
  Interface representing an HTTP error with enhanced error information
5394
6284
 
@@ -5599,7 +6489,7 @@ if (error.error?.validationErrors) {
5599
6489
  </td>
5600
6490
  <td>
5601
6491
 
5602
- [libs/ngx-utils/src/lib/interfaces/http-error.interface.ts:170](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/interfaces/http-error.interface.ts#L170)
6492
+ [libs/ngx-utils/src/lib/interfaces/http-error.interface.ts:170](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/interfaces/http-error.interface.ts#L170)
5603
6493
 
5604
6494
  </td>
5605
6495
  </tr>
@@ -5643,7 +6533,7 @@ Error.message;
5643
6533
  </td>
5644
6534
  <td>
5645
6535
 
5646
- [libs/ngx-utils/src/lib/interfaces/http-error.interface.ts:152](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/interfaces/http-error.interface.ts#L152)
6536
+ [libs/ngx-utils/src/lib/interfaces/http-error.interface.ts:152](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/interfaces/http-error.interface.ts#L152)
5647
6537
 
5648
6538
  </td>
5649
6539
  </tr>
@@ -5757,7 +6647,7 @@ if (error.status === 401) {
5757
6647
  </td>
5758
6648
  <td>
5759
6649
 
5760
- [libs/ngx-utils/src/lib/interfaces/http-error.interface.ts:138](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/interfaces/http-error.interface.ts#L138)
6650
+ [libs/ngx-utils/src/lib/interfaces/http-error.interface.ts:138](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/interfaces/http-error.interface.ts#L138)
5761
6651
 
5762
6652
  </td>
5763
6653
  </tr>
@@ -5772,7 +6662,7 @@ if (error.status === 401) {
5772
6662
  type DataFormControls<T> = { [K in keyof T]: FormControl<T[K] | null> };
5773
6663
  ```
5774
6664
 
5775
- Defined in: [libs/ngx-utils/src/lib/form/form.interfaces.ts:122](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/form/form.interfaces.ts#L122)
6665
+ Defined in: [libs/ngx-utils/src/lib/form/form.interfaces.ts:122](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/form/form.interfaces.ts#L122)
5776
6666
 
5777
6667
  Type representing the controls structure of a type-safe form
5778
6668
 
@@ -5866,7 +6756,7 @@ export class ProductFormComponent {
5866
6756
  type DataFormValues<T> = { [K in keyof T]?: T[K] | null };
5867
6757
  ```
5868
6758
 
5869
- Defined in: [libs/ngx-utils/src/lib/form/form.interfaces.ts:58](https://github.com/hichchidev/hichchi/blob/70fdee7ca8f6cceb9fa71d5e5e1eadc76e3aba50/libs/ngx-utils/src/lib/form/form.interfaces.ts#L58)
6759
+ Defined in: [libs/ngx-utils/src/lib/form/form.interfaces.ts:58](https://github.com/hichchidev/hichchi/blob/1821ea22bf9e9b89c932111f16da4943c07c58c7/libs/ngx-utils/src/lib/form/form.interfaces.ts#L58)
5870
6760
 
5871
6761
  Type representing the value structure of a type-safe form
5872
6762