0
# Services
1
2
PrimeNG provides a comprehensive set of services for global state management, utility functions, and cross-component functionality to enhance your Angular application.
3
4
## Global Services
5
6
### ConfirmationService
7
8
Manages confirmation dialogs and popups across the application.
9
10
```typescript { .api }
11
// Import
12
import { ConfirmationService } from 'primeng/api';
13
14
// Service Interface
15
class ConfirmationService {
16
// Properties
17
requireConfirmationSource: Subject<Confirmation>;
18
acceptConfirmationSource: Subject<Confirmation>;
19
20
// Methods
21
confirm(confirmation: Confirmation): this;
22
close(): this;
23
24
// Observables
25
requireConfirmation$: Observable<Confirmation>;
26
accept: Observable<Confirmation>;
27
}
28
29
// Confirmation Configuration
30
interface Confirmation {
31
message?: string;
32
key?: string;
33
icon?: string;
34
header?: string;
35
accept?: Function;
36
reject?: Function;
37
acceptLabel?: string;
38
rejectLabel?: string;
39
acceptIcon?: string;
40
rejectIcon?: string;
41
acceptVisible?: boolean;
42
rejectVisible?: boolean;
43
blockScroll?: boolean;
44
closeOnEscape?: boolean;
45
dismissableMask?: boolean;
46
defaultFocus?: string;
47
acceptButtonStyleClass?: string;
48
rejectButtonStyleClass?: string;
49
target?: EventTarget;
50
acceptEvent?: Event;
51
rejectEvent?: Event;
52
}
53
54
// Usage
55
@Component({
56
template: `
57
<p-confirmdialog></p-confirmdialog>
58
<p-button (onClick)="confirm()" label="Delete" severity="danger"></p-button>
59
`,
60
providers: [ConfirmationService]
61
})
62
export class ConfirmationExampleComponent {
63
constructor(private confirmationService: ConfirmationService) {}
64
65
confirm() {
66
this.confirmationService.confirm({
67
message: 'Are you sure you want to delete this item?',
68
header: 'Delete Confirmation',
69
icon: 'pi pi-exclamation-triangle',
70
acceptButtonStyleClass: 'p-button-danger p-button-text',
71
rejectButtonStyleClass: 'p-button-text p-button-text',
72
accept: () => {
73
// Handle acceptance
74
console.log('Confirmed');
75
},
76
reject: () => {
77
// Handle rejection
78
console.log('Rejected');
79
}
80
});
81
}
82
83
// Multiple confirmation dialogs
84
confirmWithKey() {
85
this.confirmationService.confirm({
86
key: 'custom-dialog',
87
message: 'Custom confirmation dialog',
88
header: 'Custom Header',
89
accept: () => {
90
console.log('Custom dialog accepted');
91
}
92
});
93
}
94
95
// Close all confirmations
96
closeAllConfirmations() {
97
this.confirmationService.close();
98
}
99
}
100
```
101
102
### MessageService
103
104
Handles toast notifications and inline messages throughout the application.
105
106
```typescript { .api }
107
// Import
108
import { MessageService } from 'primeng/api';
109
110
// Service Interface
111
class MessageService {
112
// Properties
113
messageSource: Subject<Message>;
114
clearSource: Subject<string>;
115
116
// Methods
117
add(message: Message): void;
118
addAll(messages: Message[]): void;
119
clear(key?: string): void;
120
121
// Observables
122
messageObserver: Observable<Message>;
123
clearObserver: Observable<string>;
124
}
125
126
// Message Configuration
127
interface Message {
128
severity?: 'success' | 'info' | 'warn' | 'error' | 'custom';
129
summary?: string;
130
detail?: string;
131
id?: any;
132
key?: string;
133
life?: number;
134
sticky?: boolean;
135
closable?: boolean;
136
data?: any;
137
icon?: string;
138
contentStyleClass?: string;
139
styleClass?: string;
140
}
141
142
// Usage
143
@Component({
144
template: `
145
<p-toast></p-toast>
146
<p-toast key="custom" position="top-left"></p-toast>
147
148
<div class="flex gap-2">
149
<p-button (onClick)="showSuccess()" label="Success" severity="success"></p-button>
150
<p-button (onClick)="showError()" label="Error" severity="danger"></p-button>
151
<p-button (onClick)="showCustom()" label="Custom" severity="help"></p-button>
152
<p-button (onClick)="showMultiple()" label="Multiple" severity="secondary"></p-button>
153
<p-button (onClick)="clear()" label="Clear"></p-button>
154
</div>
155
`,
156
providers: [MessageService]
157
})
158
export class MessageExampleComponent {
159
constructor(private messageService: MessageService) {}
160
161
showSuccess() {
162
this.messageService.add({
163
severity: 'success',
164
summary: 'Success',
165
detail: 'Operation completed successfully',
166
life: 3000
167
});
168
}
169
170
showError() {
171
this.messageService.add({
172
severity: 'error',
173
summary: 'Error',
174
detail: 'Something went wrong',
175
sticky: true
176
});
177
}
178
179
showCustom() {
180
this.messageService.add({
181
key: 'custom',
182
severity: 'info',
183
summary: 'Custom Toast',
184
detail: 'This appears in top-left corner'
185
});
186
}
187
188
showMultiple() {
189
this.messageService.addAll([
190
{ severity: 'info', summary: 'Message 1', detail: 'First message' },
191
{ severity: 'warn', summary: 'Message 2', detail: 'Second message' },
192
{ severity: 'error', summary: 'Message 3', detail: 'Third message' }
193
]);
194
}
195
196
clear() {
197
this.messageService.clear();
198
}
199
200
clearCustom() {
201
this.messageService.clear('custom');
202
}
203
}
204
```
205
206
### OverlayService
207
208
Manages overlay components and their z-index layering.
209
210
```typescript { .api }
211
// Import
212
import { OverlayService } from 'primeng/api';
213
214
// Service Interface
215
class OverlayService {
216
// Events
217
onShow: Subject<any>;
218
onHide: Subject<any>;
219
220
// Methods (internal use)
221
private add(overlay: any): void;
222
private remove(overlay: any): void;
223
}
224
225
// Usage
226
@Component({})
227
export class OverlayExampleComponent {
228
constructor(private overlayService: OverlayService) {
229
// Listen to overlay events
230
this.overlayService.onShow.subscribe((event) => {
231
console.log('Overlay shown:', event);
232
});
233
234
this.overlayService.onHide.subscribe((event) => {
235
console.log('Overlay hidden:', event);
236
});
237
}
238
}
239
```
240
241
### FilterService
242
243
Provides data filtering utilities for tables and data components.
244
245
```typescript { .api }
246
// Import
247
import { FilterService } from 'primeng/api';
248
249
// Service Interface
250
class FilterService {
251
// Methods
252
filter(data: any[], fields: string[], filterValue: any, filterMatchMode: string, filterLocale?: string): any[];
253
filters: { [key: string]: (value: any, filter: any, filterLocale?: string) => boolean };
254
255
// Built-in filter functions
256
startsWith(value: any, filter: any, filterLocale?: string): boolean;
257
contains(value: any, filter: any, filterLocale?: string): boolean;
258
notContains(value: any, filter: any, filterLocale?: string): boolean;
259
endsWith(value: any, filter: any, filterLocale?: string): boolean;
260
equals(value: any, filter: any, filterLocale?: string): boolean;
261
notEquals(value: any, filter: any, filterLocale?: string): boolean;
262
in(value: any, filter: any[]): boolean;
263
between(value: any, filter: any[]): boolean;
264
lt(value: any, filter: any, filterLocale?: string): boolean;
265
lte(value: any, filter: any, filterLocale?: string): boolean;
266
gt(value: any, filter: any, filterLocale?: string): boolean;
267
gte(value: any, filter: any, filterLocale?: string): boolean;
268
is(value: any, filter: any, filterLocale?: string): boolean;
269
isNot(value: any, filter: any, filterLocale?: string): boolean;
270
before(value: any, filter: any, filterLocale?: string): boolean;
271
after(value: any, filter: any, filterLocale?: string): boolean;
272
dateIs(value: any, filter: any): boolean;
273
dateIsNot(value: any, filter: any): boolean;
274
dateBefore(value: any, filter: any): boolean;
275
dateAfter(value: any, filter: any): boolean;
276
}
277
278
// Usage
279
@Injectable({
280
providedIn: 'root'
281
})
282
export class CustomFilterService {
283
constructor(private filterService: FilterService) {
284
// Register custom filter
285
this.filterService.filters['customFilter'] = this.customFilterFunction.bind(this);
286
}
287
288
// Custom filter function
289
customFilterFunction(value: any, filter: any): boolean {
290
if (filter === undefined || filter === null || filter.trim() === '') {
291
return true;
292
}
293
294
if (value === undefined || value === null) {
295
return false;
296
}
297
298
return value.toString().toLowerCase().includes(filter.toString().toLowerCase());
299
}
300
301
// Use filter service for custom filtering
302
filterData(data: any[], searchTerm: string): any[] {
303
return this.filterService.filter(
304
data,
305
['name', 'description'],
306
searchTerm,
307
'customFilter'
308
);
309
}
310
311
// Advanced filtering example
312
advancedFilter(products: Product[], criteria: FilterCriteria): Product[] {
313
let filtered = products;
314
315
if (criteria.name) {
316
filtered = this.filterService.filter(
317
filtered,
318
['name'],
319
criteria.name,
320
'contains'
321
);
322
}
323
324
if (criteria.priceRange) {
325
filtered = this.filterService.filter(
326
filtered,
327
['price'],
328
criteria.priceRange,
329
'between'
330
);
331
}
332
333
if (criteria.categories && criteria.categories.length > 0) {
334
filtered = this.filterService.filter(
335
filtered,
336
['category'],
337
criteria.categories,
338
'in'
339
);
340
}
341
342
return filtered;
343
}
344
}
345
346
interface FilterCriteria {
347
name?: string;
348
priceRange?: [number, number];
349
categories?: string[];
350
}
351
```
352
353
### TreeDragDropService
354
355
Handles drag and drop operations for tree components.
356
357
```typescript { .api }
358
// Import
359
import { TreeDragDropService } from 'primeng/api';
360
361
// Service Interface
362
class TreeDragDropService {
363
// Properties
364
dragStartSource: Subject<TreeNodeDragEvent>;
365
dragStopSource: Subject<TreeNodeDragEvent>;
366
367
// Methods
368
startDrag(event: TreeNodeDragEvent): void;
369
stopDrag(event: TreeNodeDragEvent): void;
370
371
// Observables
372
dragStart$: Observable<TreeNodeDragEvent>;
373
dragStop$: Observable<TreeNodeDragEvent>;
374
}
375
376
// Drag Event Interface
377
interface TreeNodeDragEvent {
378
tree?: any;
379
node?: TreeNode;
380
subNodes?: TreeNode[];
381
index?: number;
382
scope?: any;
383
}
384
385
// Usage
386
@Component({
387
template: `
388
<div class="grid">
389
<div class="col-6">
390
<p-tree
391
[value]="files1"
392
[draggableNodes]="true"
393
draggableScope="files"
394
droppableScope="files"
395
selectionMode="single"
396
[(selection)]="selectedFile1">
397
</p-tree>
398
</div>
399
<div class="col-6">
400
<p-tree
401
[value]="files2"
402
[draggableNodes]="true"
403
[droppableNodes]="true"
404
draggableScope="files"
405
droppableScope="files"
406
selectionMode="single"
407
[(selection)]="selectedFile2">
408
</p-tree>
409
</div>
410
</div>
411
`,
412
providers: [TreeDragDropService]
413
})
414
export class TreeDragDropExampleComponent {
415
files1: TreeNode[] = [];
416
files2: TreeNode[] = [];
417
selectedFile1: TreeNode | undefined;
418
selectedFile2: TreeNode | undefined;
419
420
constructor(private treeDragDropService: TreeDragDropService) {
421
// Listen to drag events
422
this.treeDragDropService.dragStart$.subscribe((event: TreeNodeDragEvent) => {
423
console.log('Drag started:', event);
424
});
425
426
this.treeDragDropService.dragStop$.subscribe((event: TreeNodeDragEvent) => {
427
console.log('Drag stopped:', event);
428
});
429
}
430
}
431
```
432
433
### ContextMenuService
434
435
Manages context menu state and interactions.
436
437
```typescript { .api }
438
// Import
439
import { ContextMenuService } from 'primeng/api';
440
441
// Service Interface (internal use)
442
class ContextMenuService {
443
activeContextMenu: any;
444
445
show(contextMenu: any): void;
446
reset(): void;
447
}
448
449
// Usage with ContextMenu component
450
@Component({
451
template: `
452
<p-contextmenu #cm [global]="true" [model]="items"></p-contextmenu>
453
454
<div class="card">
455
<img
456
src="assets/showcase/images/demo/nature/nature3.jpg"
457
alt="Logo"
458
(contextmenu)="cm.show($event)"
459
class="w-full md:w-auto">
460
</div>
461
`
462
})
463
export class ContextMenuExampleComponent {
464
items: MenuItem[] = [];
465
466
ngOnInit() {
467
this.items = [
468
{ label: 'View', icon: 'pi pi-fw pi-search' },
469
{ label: 'Delete', icon: 'pi pi-fw pi-times' }
470
];
471
}
472
}
473
```
474
475
## Utility Services and Classes
476
477
### DomHandler
478
479
Utility class for DOM manipulation and calculations.
480
481
```typescript { .api }
482
// Import
483
import { DomHandler } from 'primeng/dom';
484
485
// Utility Class (static methods)
486
class DomHandler {
487
// Element queries
488
static addClass(element: any, className: string): void;
489
static removeClass(element: any, className: string): void;
490
static hasClass(element: any, className: string): boolean;
491
static siblings(element: any): any;
492
static find(element: any, selector: string): any[];
493
static findSingle(element: any, selector: string): any;
494
static index(element: any): number;
495
static indexWithinGroup(element: any, attributeName: string): number;
496
497
// Positioning and sizing
498
static getOuterWidth(el: any, margin?: boolean): number;
499
static getOuterHeight(el: any, margin?: boolean): number;
500
static getHiddenElementOuterWidth(element: any): number;
501
static getHiddenElementOuterHeight(element: any): number;
502
static getClientHeight(element: any, margin?: boolean): number;
503
static getViewport(): any;
504
static getOffset(el: any): any;
505
static generateZIndex(): number;
506
static getCurrentZIndex(): number;
507
508
// Scrolling
509
static scrollInView(container: any, item: any): void;
510
static fadeIn(element: any, duration: number): void;
511
static fadeOut(element: any, duration: number): void;
512
513
// Focus management
514
static focus(el: any, options?: FocusOptions): void;
515
static getFocusableElements(element: any): any[];
516
static getFirstFocusableElement(element: any): any;
517
static getLastFocusableElement(element: any): any;
518
519
// Browser detection
520
static isIOS(): boolean;
521
static isAndroid(): boolean;
522
static isTouchDevice(): boolean;
523
524
// Calculations
525
static calculateScrollbarWidth(): number;
526
static invokeElementMethod(element: any, methodName: string, args?: any[]): void;
527
static clearSelection(): void;
528
static getBrowser(): any;
529
}
530
531
// Usage
532
@Component({})
533
export class DomUtilityComponent {
534
ngAfterViewInit() {
535
const element = document.getElementById('myElement');
536
537
// Add/remove classes
538
DomHandler.addClass(element, 'highlight');
539
DomHandler.removeClass(element, 'old-class');
540
541
// Check if element has class
542
if (DomHandler.hasClass(element, 'active')) {
543
console.log('Element is active');
544
}
545
546
// Get dimensions
547
const width = DomHandler.getOuterWidth(element, true);
548
const height = DomHandler.getOuterHeight(element, true);
549
550
// Get viewport info
551
const viewport = DomHandler.getViewport();
552
console.log('Viewport:', viewport);
553
554
// Focus management
555
const focusableElements = DomHandler.getFocusableElements(element);
556
if (focusableElements.length > 0) {
557
DomHandler.focus(focusableElements[0]);
558
}
559
560
// Browser detection
561
if (DomHandler.isTouchDevice()) {
562
console.log('Touch device detected');
563
}
564
565
// Generate z-index
566
const zIndex = DomHandler.generateZIndex();
567
element.style.zIndex = zIndex.toString();
568
}
569
}
570
```
571
572
### ObjectUtils
573
574
Utility functions for object manipulation and comparison.
575
576
```typescript { .api }
577
// Import
578
import { ObjectUtils } from 'primeng/utils';
579
580
// Utility Class (static methods)
581
class ObjectUtils {
582
// Object property access
583
static equals(obj1: any, obj2: any, field?: string): boolean;
584
static deepEquals(a: any, b: any): boolean;
585
static resolveFieldData(data: any, field: string): any;
586
static filter(value: any[], fields: any[], filterValue: any): any[];
587
588
// Array utilities
589
static reorderArray(value: any[], from: number, to: number): void;
590
static findIndexInList(value: any, list: any[], dataKey?: string): number;
591
static contains(value: any, list: any[]): boolean;
592
static insertIntoOrderedArray(item: any, index: number, arr: any[], sourceArr: any[]): void;
593
static findDiffKeys(obj1: any, obj2: any): any;
594
595
// Type checking
596
static isArray(value: any, empty?: boolean): boolean;
597
static isDate(value: any): boolean;
598
static isEmpty(value: any): boolean;
599
static isNotEmpty(value: any): boolean;
600
static isFunction(value: any): boolean;
601
static isObject(value: any, empty?: boolean): boolean;
602
static isString(value: any, empty?: boolean): boolean;
603
604
// Data transformation
605
static removeAccents(str: string): string;
606
static toFlatCase(str: string): string;
607
static toCapitalCase(str: string): string;
608
static uuid(): string;
609
}
610
611
// Usage
612
@Component({})
613
export class ObjectUtilityComponent {
614
ngOnInit() {
615
// Object comparison
616
const obj1 = { name: 'John', age: 30 };
617
const obj2 = { name: 'John', age: 30 };
618
const areEqual = ObjectUtils.deepEquals(obj1, obj2); // true
619
620
// Field data resolution
621
const user = { profile: { name: 'John Doe' } };
622
const name = ObjectUtils.resolveFieldData(user, 'profile.name'); // 'John Doe'
623
624
// Array filtering
625
const users = [
626
{ name: 'John Doe', city: 'New York' },
627
{ name: 'Jane Smith', city: 'London' }
628
];
629
const filtered = ObjectUtils.filter(users, ['name', 'city'], 'John'); // [{ name: 'John Doe', city: 'New York' }]
630
631
// Type checking
632
if (ObjectUtils.isArray(users)) {
633
console.log('users is an array');
634
}
635
636
if (ObjectUtils.isEmpty(null)) {
637
console.log('Value is empty');
638
}
639
640
// String utilities
641
const flatCase = ObjectUtils.toFlatCase('Hello World'); // 'helloworld'
642
const capitalCase = ObjectUtils.toCapitalCase('hello world'); // 'Hello World'
643
const cleanStr = ObjectUtils.removeAccents('café'); // 'cafe'
644
645
// Generate UUID
646
const id = ObjectUtils.uuid();
647
console.log('Generated UUID:', id);
648
649
// Array manipulation
650
const items = [1, 2, 3, 4, 5];
651
ObjectUtils.reorderArray(items, 0, 4); // Move first item to last position
652
console.log(items); // [2, 3, 4, 5, 1]
653
654
// Find index in array
655
const index = ObjectUtils.findIndexInList({ id: 2 }, users, 'id');
656
console.log('Index:', index);
657
}
658
}
659
```
660
661
### UniqueComponentId
662
663
Generates unique IDs for components.
664
665
```typescript { .api }
666
// Import
667
import { UniqueComponentId } from 'primeng/utils';
668
669
// Function
670
function UniqueComponentId(prefix?: string): string;
671
672
// Usage
673
@Component({
674
template: `
675
<div [id]="elementId">
676
<label [for]="inputId">Label</label>
677
<input [id]="inputId" type="text">
678
</div>
679
`
680
})
681
export class UniqueIdComponent {
682
elementId: string;
683
inputId: string;
684
685
constructor() {
686
this.elementId = UniqueComponentId('element');
687
this.inputId = UniqueComponentId('input');
688
// Results in IDs like: 'element_1', 'input_2', etc.
689
}
690
}
691
```
692
693
## Configuration Service
694
695
### PrimeNG Configuration
696
697
Global configuration service for theme, locale, and behavior settings.
698
699
```typescript { .api }
700
// Import
701
import { PrimeNG, providePrimeNG } from 'primeng/config';
702
703
// Configuration Interface
704
interface PrimeNGConfigType {
705
ripple?: boolean;
706
inputStyle?: 'outlined' | 'filled';
707
overlayOptions?: OverlayOptions;
708
csp?: {
709
nonce?: string;
710
};
711
filterMatchModeOptions?: {
712
text?: FilterMatchMode[];
713
numeric?: FilterMatchMode[];
714
date?: FilterMatchMode[];
715
};
716
translation?: Translation;
717
zIndex?: {
718
modal?: number;
719
overlay?: number;
720
menu?: number;
721
tooltip?: number;
722
};
723
theme?: {
724
preset?: any;
725
options?: any;
726
};
727
}
728
729
// Service Class
730
@Injectable({
731
providedIn: 'root'
732
})
733
export class PrimeNG {
734
ripple: Signal<boolean>;
735
theme: Signal<any>;
736
overlayOptions: Signal<OverlayOptions>;
737
csp: Signal<any>;
738
filterMatchModeOptions: Signal<any>;
739
translation: Signal<any>;
740
zIndex: Signal<any>;
741
inputStyle: Signal<string>;
742
743
update(config: PrimeNGConfigType): void;
744
getTranslation(key: string): string;
745
}
746
747
// Global Provider Setup
748
import { bootstrapApplication } from '@angular/platform-browser';
749
750
bootstrapApplication(AppComponent, {
751
providers: [
752
providePrimeNG({
753
theme: {
754
preset: 'Aura',
755
options: {
756
darkModeSelector: '.p-dark'
757
}
758
},
759
ripple: true,
760
inputStyle: 'outlined',
761
zIndex: {
762
modal: 1100,
763
overlay: 1000,
764
menu: 1000,
765
tooltip: 1100
766
},
767
translation: {
768
accept: 'Accept',
769
reject: 'Reject',
770
choose: 'Choose',
771
upload: 'Upload',
772
cancel: 'Cancel',
773
dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
774
dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
775
dayNamesMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
776
monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
777
monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
778
}
779
})
780
]
781
});
782
783
// Component Usage
784
@Component({})
785
export class ConfigExampleComponent {
786
constructor(private primeng: PrimeNG) {}
787
788
ngOnInit() {
789
// Get current configuration
790
console.log('Ripple enabled:', this.primeng.ripple());
791
console.log('Current theme:', this.primeng.theme());
792
console.log('Input style:', this.primeng.inputStyle());
793
794
// Update configuration
795
this.primeng.update({
796
ripple: false,
797
inputStyle: 'filled'
798
});
799
800
// Get translation
801
const acceptLabel = this.primeng.getTranslation('accept');
802
console.log('Accept label:', acceptLabel);
803
}
804
805
// Dynamic theme switching
806
toggleTheme() {
807
const currentTheme = this.primeng.theme();
808
const isDark = currentTheme?.options?.darkModeSelector === '.p-dark';
809
810
this.primeng.update({
811
theme: {
812
preset: 'Aura',
813
options: {
814
darkModeSelector: isDark ? false : '.p-dark'
815
}
816
}
817
});
818
819
// Toggle CSS class on document
820
if (isDark) {
821
document.documentElement.classList.remove('p-dark');
822
} else {
823
document.documentElement.classList.add('p-dark');
824
}
825
}
826
}
827
```
828
829
## Custom Service Integration
830
831
Creating custom services that work with PrimeNG:
832
833
```typescript
834
@Injectable({
835
providedIn: 'root'
836
})
837
export class CustomDataService {
838
constructor(
839
private messageService: MessageService,
840
private confirmationService: ConfirmationService,
841
private filterService: FilterService
842
) {}
843
844
async saveData(data: any): Promise<boolean> {
845
try {
846
// Simulate API call
847
await this.simulateApiCall();
848
849
this.messageService.add({
850
severity: 'success',
851
summary: 'Success',
852
detail: 'Data saved successfully'
853
});
854
855
return true;
856
} catch (error) {
857
this.messageService.add({
858
severity: 'error',
859
summary: 'Error',
860
detail: 'Failed to save data'
861
});
862
863
return false;
864
}
865
}
866
867
confirmDelete(item: any): Promise<boolean> {
868
return new Promise((resolve) => {
869
this.confirmationService.confirm({
870
message: `Are you sure you want to delete ${item.name}?`,
871
header: 'Delete Confirmation',
872
icon: 'pi pi-exclamation-triangle',
873
accept: () => resolve(true),
874
reject: () => resolve(false)
875
});
876
});
877
}
878
879
searchAndFilter(data: any[], searchTerm: string, fields: string[]): any[] {
880
if (!searchTerm) {
881
return data;
882
}
883
884
return this.filterService.filter(data, fields, searchTerm, 'contains');
885
}
886
887
private simulateApiCall(): Promise<void> {
888
return new Promise((resolve, reject) => {
889
setTimeout(() => {
890
if (Math.random() > 0.1) { // 90% success rate
891
resolve();
892
} else {
893
reject(new Error('Simulated API error'));
894
}
895
}, 1000);
896
});
897
}
898
}
899
```
900
901
## Service Dependencies
902
903
When using PrimeNG services, ensure proper dependency injection:
904
905
```typescript
906
// Module setup (if using NgModules)
907
@NgModule({
908
providers: [
909
ConfirmationService,
910
MessageService,
911
// Other services are provided automatically
912
]
913
})
914
export class AppModule {}
915
916
// Standalone component setup
917
@Component({
918
standalone: true,
919
providers: [
920
ConfirmationService,
921
MessageService
922
]
923
})
924
export class StandaloneComponent {}
925
```
926
927
PrimeNG services provide a robust foundation for building complex Angular applications with consistent user experience patterns, global state management, and utility functions that enhance development productivity.