{"id":36807,"date":"2026-04-18T21:49:08","date_gmt":"2026-04-18T18:49:08","guid":{"rendered":"https:\/\/kamil-abzalov.com\/tutorials\/create-custom-validators-in-angular-application\/"},"modified":"2026-04-18T22:03:46","modified_gmt":"2026-04-18T19:03:46","slug":"create-custom-validators-in-angular-application","status":"publish","type":"post","link":"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/","title":{"rendered":"Create custom validators in Angular application"},"content":{"rendered":"<p>[et_pb_section fb_built=&#8221;1&#8243; fullwidth=&#8221;on&#8221; admin_label=&#8221;Header&#8221; _builder_version=&#8221;4.20.0&#8243; use_background_color_gradient=&#8221;on&#8221; background_color_gradient_direction=&#8221;163deg&#8221; background_color_gradient_stops=&#8221;rgba(0,0,0,0.02) 50%|#ffffff 50%&#8221; background_color_gradient_start=&#8221;rgba(0,0,0,0.02)&#8221; background_color_gradient_start_position=&#8221;50%&#8221; background_color_gradient_end=&#8221;#ffffff&#8221; background_color_gradient_end_position=&#8221;0%&#8221; background_image=&#8221;https:\/\/kamil-abzalov.com\/wp-content\/uploads\/2021\/12\/web-dev-03.png&#8221; parallax=&#8221;on&#8221; animation_style=&#8221;fade&#8221; collapsed=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_fullwidth_header title=&#8221;Create custom validators in Angular application&#8221; content_max_width=&#8221;640px&#8221; _builder_version=&#8221;4.27.6&#8243; title_font=&#8221;Roboto|700|||||||&#8221; title_line_height=&#8221;1.5em&#8221; content_font=&#8221;Roboto||||||||&#8221; content_font_size=&#8221;16px&#8221; content_line_height=&#8221;2em&#8221; subhead_font=&#8221;|700||on|||||&#8221; subhead_font_size=&#8221;14px&#8221; subhead_letter_spacing=&#8221;2px&#8221; subhead_line_height=&#8221;2em&#8221; background_color=&#8221;rgba(0,0,0,0)&#8221; custom_button_one=&#8221;on&#8221; button_one_text_size=&#8221;14px&#8221; button_one_text_color=&#8221;#ffffff&#8221; button_one_bg_color=&#8221;#0054ff&#8221; button_one_border_width=&#8221;14px&#8221; button_one_border_color=&#8221;rgba(0,0,0,0)&#8221; button_one_border_radius=&#8221;0px&#8221; button_one_letter_spacing=&#8221;2px&#8221; button_one_font=&#8221;|600||on|||||&#8221; button_one_icon=&#8221;&#x39;||divi||400&#8243; button_one_on_hover=&#8221;off&#8221; custom_button_two=&#8221;on&#8221; button_two_text_size=&#8221;14px&#8221; button_two_text_color=&#8221;#0054ff&#8221; button_two_bg_color=&#8221;rgba(255,255,255,0)&#8221; button_two_border_width=&#8221;12px&#8221; button_two_border_color=&#8221;rgba(0,0,0,0)&#8221; button_two_border_radius=&#8221;0px&#8221; button_two_letter_spacing=&#8221;2px&#8221; button_two_font=&#8221;|600||on|||||&#8221; button_two_icon=&#8221;&#x39;||divi||400&#8243; button_two_on_hover=&#8221;off&#8221; background_layout=&#8221;light&#8221; custom_margin=&#8221;|||&#8221; custom_padding=&#8221;6vw||6vw||false|false&#8221; animation_style=&#8221;zoom&#8221; animation_intensity_zoom=&#8221;-5%&#8221; title_font_size_tablet=&#8221;&#8221; title_font_size_phone=&#8221;25px&#8221; title_font_size_last_edited=&#8221;on|desktop&#8221; box_shadow_style_button_two=&#8221;preset1&#8243; box_shadow_vertical_button_two=&#8221;0px&#8221; box_shadow_blur_button_two=&#8221;0px&#8221; box_shadow_spread_button_two=&#8221;2px&#8221; box_shadow_color_button_two=&#8221;#0054ff&#8221; button_one_letter_spacing_hover=&#8221;2px&#8221; button_two_letter_spacing_hover=&#8221;2px&#8221; global_colors_info=&#8221;{}&#8221; button_one_text_size__hover_enabled=&#8221;off&#8221; button_two_text_size__hover_enabled=&#8221;off&#8221; button_one_text_color__hover_enabled=&#8221;off&#8221; button_two_text_color__hover_enabled=&#8221;off&#8221; button_one_border_width__hover_enabled=&#8221;off&#8221; button_two_border_width__hover_enabled=&#8221;off&#8221; button_one_border_color__hover_enabled=&#8221;off&#8221; button_two_border_color__hover_enabled=&#8221;off&#8221; button_one_border_radius__hover_enabled=&#8221;off&#8221; button_two_border_radius__hover_enabled=&#8221;off&#8221; button_one_letter_spacing__hover_enabled=&#8221;on&#8221; button_one_letter_spacing__hover=&#8221;2px&#8221; button_two_letter_spacing__hover_enabled=&#8221;on&#8221; button_two_letter_spacing__hover=&#8221;2px&#8221; button_one_bg_color__hover_enabled=&#8221;off&#8221; button_two_bg_color__hover_enabled=&#8221;off&#8221;][\/et_pb_fullwidth_header][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.21.2&#8243; _module_preset=&#8221;default&#8221; collapsed=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.21.2&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.21.2&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_dcsbcm_divi_breadcrumbs_module homebreadcrumbtext=&#8221;Home&#8221; hide_currentbreadcrumb=&#8221;off&#8221; _builder_version=&#8221;4.27.6&#8243; fontsbreadcrumbs_font_size_tablet=&#8221;51&#8243; fontsbreadcrumbs_line_height_tablet=&#8221;2&#8243; fontsseperator_font_size_tablet=&#8221;51&#8243; fontsseperator_line_height_tablet=&#8221;2&#8243; fontsbreadcrumblinks_font_size_tablet=&#8221;51&#8243; fontsbreadcrumblinks_line_height_tablet=&#8221;2&#8243; z_index_tablet=&#8221;500&#8243; fontsbreadcrumbs_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; fontsbreadcrumbs_text_shadow_vertical_length_tablet=&#8221;0px&#8221; fontsbreadcrumbs_text_shadow_blur_strength_tablet=&#8221;1px&#8221; fontsseperator_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; fontsseperator_text_shadow_vertical_length_tablet=&#8221;0px&#8221; fontsseperator_text_shadow_blur_strength_tablet=&#8221;1px&#8221; fontsbreadcrumblinks_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; fontsbreadcrumblinks_text_shadow_vertical_length_tablet=&#8221;0px&#8221; fontsbreadcrumblinks_text_shadow_blur_strength_tablet=&#8221;1px&#8221; box_shadow_horizontal_tablet=&#8221;0px&#8221; box_shadow_vertical_tablet=&#8221;0px&#8221; box_shadow_blur_tablet=&#8221;40px&#8221; box_shadow_spread_tablet=&#8221;0px&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_dcsbcm_divi_breadcrumbs_module][et_pb_text _builder_version=&#8221;4.27.6&#8243; z_index_tablet=&#8221;500&#8243; text_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; text_text_shadow_vertical_length_tablet=&#8221;0px&#8221; text_text_shadow_blur_strength_tablet=&#8221;1px&#8221; link_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; link_text_shadow_vertical_length_tablet=&#8221;0px&#8221; link_text_shadow_blur_strength_tablet=&#8221;1px&#8221; ul_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; ul_text_shadow_vertical_length_tablet=&#8221;0px&#8221; ul_text_shadow_blur_strength_tablet=&#8221;1px&#8221; ol_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; ol_text_shadow_vertical_length_tablet=&#8221;0px&#8221; ol_text_shadow_blur_strength_tablet=&#8221;1px&#8221; quote_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; quote_text_shadow_vertical_length_tablet=&#8221;0px&#8221; quote_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_2_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_2_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_2_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_3_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_3_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_3_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_4_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_4_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_4_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_5_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_5_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_5_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_6_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_6_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_6_text_shadow_blur_strength_tablet=&#8221;1px&#8221; box_shadow_horizontal_tablet=&#8221;0px&#8221; box_shadow_vertical_tablet=&#8221;0px&#8221; box_shadow_blur_tablet=&#8221;40px&#8221; box_shadow_spread_tablet=&#8221;0px&#8221; global_colors_info=&#8221;{}&#8221;]In this video, we\u2019ll see how to add custom sync and async validators in an Angular application, and also how to handle Observable unsubscription.[\/et_pb_text][et_pb_video src=&#8221;https:\/\/youtu.be\/5HsTMIIm5Vk&#8221; disabled_on=&#8221;off|off|off&#8221; _builder_version=&#8221;4.27.6&#8243; global_colors_info=&#8221;{}&#8221;][\/et_pb_video][et_pb_text _builder_version=&#8221;4.27.6&#8243; hover_enabled=&#8221;0&#8243; z_index_tablet=&#8221;500&#8243; text_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; text_text_shadow_vertical_length_tablet=&#8221;0px&#8221; text_text_shadow_blur_strength_tablet=&#8221;1px&#8221; link_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; link_text_shadow_vertical_length_tablet=&#8221;0px&#8221; link_text_shadow_blur_strength_tablet=&#8221;1px&#8221; ul_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; ul_text_shadow_vertical_length_tablet=&#8221;0px&#8221; ul_text_shadow_blur_strength_tablet=&#8221;1px&#8221; ol_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; ol_text_shadow_vertical_length_tablet=&#8221;0px&#8221; ol_text_shadow_blur_strength_tablet=&#8221;1px&#8221; quote_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; quote_text_shadow_vertical_length_tablet=&#8221;0px&#8221; quote_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_2_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_2_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_2_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_3_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_3_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_3_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_4_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_4_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_4_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_5_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_5_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_5_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_6_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_6_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_6_text_shadow_blur_strength_tablet=&#8221;1px&#8221; box_shadow_horizontal_tablet=&#8221;0px&#8221; box_shadow_vertical_tablet=&#8221;0px&#8221; box_shadow_blur_tablet=&#8221;40px&#8221; box_shadow_spread_tablet=&#8221;0px&#8221; global_colors_info=&#8221;{}&#8221; sticky_enabled=&#8221;0&#8243;]First, we will add an Observable unsubscription mechanism. This is useful in any application to avoid memory leaks. In modern Angular, there is a takeUntilDestroyed() operator. It takes an instance of the built-in DestroyRef class as a parameter. This class allows you to register callbacks that are triggered when a component (or directive) is destroyed.<\/p>\n<p>We will also add validators. In Angular, validators can be synchronous or asynchronous. The framework provides several built-in synchronous validators (based on HTML5 validation). A validator in Angular is a function (ValidatorFn) that takes a control (AbstractControl) and returns either null or a ValidationErrors object.[\/et_pb_text][et_pb_dmb_code_snippet title=&#8221;common-validators.ts&#8221; code=&#8221;aW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBWYWxpZGF0aW9uRXJyb3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnOwoKZXhwb3J0IGNsYXNzIENvbW1vblZhbGlkYXRvcnMgewogIHN0YXRpYyBwcmV2ZW50RW1wdHlWYWx1ZShjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCB7CiAgICByZXR1cm4gY29udHJvbC52YWx1ZS50cmltKCkgPyBudWxsIDogeyBlbXB0eVZhbHVlOiB0cnVlIH07CiAgfQp9Cg==&#8221; copy_button=&#8221;on&#8221; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_dmb_code_snippet][et_pb_dmb_code_snippet title=&#8221;is-unuqiue-post-title.ts&#8221; code=&#8221;aW1wb3J0IHsgbWFwLCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnOwppbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIEFzeW5jVmFsaWRhdG9yLCBWYWxpZGF0aW9uRXJyb3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnOwppbXBvcnQgeyBpbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJzsKaW1wb3J0IHsgUG9zdFNlcnZpY2UgfSBmcm9tICcuLi8uLi9mZWF0dXJlcy9wb3N0cy9zZXJ2aWNlcy9wb3N0LXNlcnZpY2UnOwoKQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSkKZXhwb3J0IGNsYXNzIElzVW51cWl1ZVBvc3RUaXRsZVZhbGlkYXRvciBpbXBsZW1lbnRzIEFzeW5jVmFsaWRhdG9yIHsKICBwcml2YXRlIHBvc3RTZXJ2aWNlID0gaW5qZWN0KFBvc3RTZXJ2aWNlKTsKCiAgdmFsaWRhdGUoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogT2JzZXJ2YWJsZTxWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbD4gewogICAgY29uc3QgcG9zdFRpdGxlID0gY29udHJvbC52YWx1ZS50cmltKCk7CiAgICBpZiAoIXBvc3RUaXRsZSkgewogICAgICByZXR1cm4gb2YobnVsbCk7CiAgICB9CiAgICByZXR1cm4gdGhpcy5wb3N0U2VydmljZQogICAgICAuY2hlY2tQb3N0VGl0bGUocG9zdFRpdGxlKQogICAgICAucGlwZShtYXAoKHJlc3VsdCkgPT4gKHJlc3VsdC5sZW5ndGggPyB7IHRpdGxlRXhpc3RzOiB0cnVlIH0gOiBudWxsKSkpOwogIH0KfQo=&#8221; copy_button=&#8221;on&#8221; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_dmb_code_snippet][et_pb_dmb_code_snippet title=&#8221;post-service.ts&#8221; code=&#8221;aW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cFBhcmFtcyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJzsKaW1wb3J0IHsgaW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7CmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJzsKCkBJbmplY3RhYmxlKHsKICBwcm92aWRlZEluOiAncm9vdCcsCn0pCmV4cG9ydCBjbGFzcyBQb3N0U2VydmljZSB7CiAgcHJpdmF0ZSByZWFkb25seSBhcGkgPSAnaHR0cHM6Ly9qc29ucGxhY2Vob2xkZXIudHlwaWNvZGUuY29tJzsKCiAgcHJpdmF0ZSBodHRwID0gaW5qZWN0KEh0dHBDbGllbnQpOwoKICBjcmVhdGVQb3N0KHRpdGxlOiBzdHJpbmcsIGJvZHk6IHN0cmluZywgdXNlcklkOiBudW1iZXIpOiBPYnNlcnZhYmxlPHZvaWQ+IHsKICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDx2b2lkPihgJHt0aGlzLmFwaX0vcG9zdHNgLCB7IHRpdGxlLCBib2R5LCB1c2VySWQgfSk7CiAgfQoKICBjaGVja1Bvc3RUaXRsZSh0aXRsZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHsKICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKCkuc2V0KCd0aXRsZScsIHRpdGxlKTsKICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueT4oYCR7dGhpcy5hcGl9L3Bvc3RzYCwge3BhcmFtc30pOwogIH0KfQo=&#8221; copy_button=&#8221;on&#8221; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_dmb_code_snippet][et_pb_dmb_code_snippet title=&#8221;post-form.ts&#8221; code=&#8221;aW1wb3J0IHsgQ29tcG9uZW50LCBEZXN0cm95UmVmLCBpbmplY3QsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJzsKaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7CmltcG9ydCB7IE1hdEZvcm1GaWVsZE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnOwppbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nOwppbXBvcnQgewogIEZvcm1CdWlsZGVyLAogIEZvcm1Db250cm9sLAogIEZvcm1Hcm91cCwKICBSZWFjdGl2ZUZvcm1zTW9kdWxlLAogIFZhbGlkYXRvcnMsCn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnOwppbXBvcnQgeyBQb3N0U2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uLy4uL3Bvc3RzL3NlcnZpY2VzL3Bvc3Qtc2VydmljZSc7CmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJzsKaW1wb3J0IHsgQ29tbW9uVmFsaWRhdG9ycyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL2NvcmUvdmFsaWRhdG9ycy9jb21tb24tdmFsaWRhdG9ycyc7CmltcG9ydCB7IElzVW51cWl1ZVBvc3RUaXRsZVZhbGlkYXRvciB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL2NvcmUvdmFsaWRhdG9ycy9pcy11bnVxaXVlLXBvc3QtdGl0bGUnOwoKaW50ZXJmYWNlIFBvc3RGb3JtR3JvdXAgewogIHBvc3RUaXRsZTogRm9ybUNvbnRyb2w8c3RyaW5nPjsKICBwb3N0Q29udGVudDogRm9ybUNvbnRyb2w8c3RyaW5nPjsKfQoKQENvbXBvbmVudCh7CiAgc2VsZWN0b3I6ICdhcHAtcG9zdC1mb3JtJywKICBpbXBvcnRzOiBbTWF0Rm9ybUZpZWxkTW9kdWxlLCBNYXRJbnB1dE1vZHVsZSwgTWF0QnV0dG9uTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlXSwKICB0ZW1wbGF0ZVVybDogJy4vcG9zdC1mb3JtLmh0bWwnLAogIHN0eWxlVXJsOiAnLi9wb3N0LWZvcm0uc2NzcycsCn0pCmV4cG9ydCBjbGFzcyBQb3N0Rm9ybSBpbXBsZW1lbnRzIE9uSW5pdCB7CiAgcHJvdGVjdGVkIGZvcm0hOiBGb3JtR3JvdXA8UG9zdEZvcm1Hcm91cD47CgogIHByaXZhdGUgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTsKICBwcml2YXRlIGlzVW5pcXVlUG9zdFRpdGxlVmFsaWRhdG9yID0gaW5qZWN0KElzVW51cWl1ZVBvc3RUaXRsZVZhbGlkYXRvcik7CgogIEBJbnB1dCgpIHVzZXJJZCA9IDA7CgogIGNvbnN0cnVjdG9yKAogICAgcHJpdmF0ZSBmb3JtQnVpbGRlcjogRm9ybUJ1aWxkZXIsCiAgICBwcml2YXRlIHBvc3RTZXJ2aWNlOiBQb3N0U2VydmljZSwKICApIHt9CgogIG5nT25Jbml0KCk6IHZvaWQgewogICAgdGhpcy5mb3JtID0gdGhpcy5mb3JtQnVpbGRlci5ncm91cCh7CiAgICAgIHBvc3RUaXRsZTogbmV3IEZvcm1Db250cm9sPHN0cmluZz4oJycsIHsKICAgICAgICBub25OdWxsYWJsZTogdHJ1ZSwKICAgICAgICB2YWxpZGF0b3JzOiBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgQ29tbW9uVmFsaWRhdG9ycy5wcmV2ZW50RW1wdHlWYWx1ZV0sCiAgICAgICAgYXN5bmNWYWxpZGF0b3JzOiBbCiAgICAgICAgICB0aGlzLmlzVW5pcXVlUG9zdFRpdGxlVmFsaWRhdG9yLnZhbGlkYXRlLmJpbmQodGhpcy5pc1VuaXF1ZVBvc3RUaXRsZVZhbGlkYXRvciksCiAgICAgICAgXSwKICAgICAgICB1cGRhdGVPbjogJ2JsdXInLAogICAgICB9KSwKICAgICAgcG9zdENvbnRlbnQ6IG5ldyBGb3JtQ29udHJvbDxzdHJpbmc+KCcnLCB7CiAgICAgICAgbm9uTnVsbGFibGU6IHRydWUsCiAgICAgICAgdmFsaWRhdG9yczogW1ZhbGlkYXRvcnMucmVxdWlyZWRdLAogICAgICB9KSwKICAgIH0pOwogIH0KCiAgcHJvdGVjdGVkIGNyZWF0ZVBvc3QoKSB7CiAgICBpZiAodGhpcy5mb3JtLmludmFsaWQgfHwgIXRoaXMudXNlcklkKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IGZvcm1WYWx1ZSA9IHRoaXMuZm9ybS5nZXRSYXdWYWx1ZSgpOwogICAgdGhpcy5wb3N0U2VydmljZQogICAgICAuY3JlYXRlUG9zdChmb3JtVmFsdWUucG9zdFRpdGxlLCBmb3JtVmFsdWUucG9zdENvbnRlbnQsIHRoaXMudXNlcklkKQogICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkKICAgICAgLnN1YnNjcmliZSgpOwogIH0KfQo=&#8221; copy_button=&#8221;on&#8221; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_dmb_code_snippet][et_pb_dmb_code_snippet title=&#8221;post-form.html&#8221; code=&#8221;PGgxPkNyZWF0ZSBuZXcgcG9zdDwvaDE+Cgo8Zm9ybSBbZm9ybUdyb3VwXT0iZm9ybSIgKG5nU3VibWl0KT0iY3JlYXRlUG9zdCgpIj4KICA8ZGl2PgogICAgPG1hdC1mb3JtLWZpZWxkPgogICAgICA8bWF0LWxhYmVsPkVudGVyIHBvc3QgdGl0bGU8L21hdC1sYWJlbD4KICAgICAgPGlucHV0IG1hdElucHV0IHBsYWNlaG9sZGVyPSJQb3N0U2VydmljZSB0aXRsZSIgZm9ybUNvbnRyb2xOYW1lPSJwb3N0VGl0bGUiIC8+CiAgICAgIEBpZiAoZm9ybS5jb250cm9scy5wb3N0VGl0bGUuaGFzRXJyb3IoJ2VtcHR5VmFsdWUnKSkgewogICAgICAgIDxtYXQtZXJyb3I+SW52YWxpZCB2YWx1ZTwvbWF0LWVycm9yPgogICAgICB9CgogICAgICBAaWYgKGZvcm0uY29udHJvbHMucG9zdFRpdGxlLmhhc0Vycm9yKCd0aXRsZUV4aXN0cycpKSB7CiAgICAgICAgPG1hdC1lcnJvcj5UaXRsZSBpcyBub3QgdW5pcXVlPC9tYXQtZXJyb3I+CiAgICAgIH0KICAgIDwvbWF0LWZvcm0tZmllbGQ+CiAgPC9kaXY+CgogIDxtYXQtZm9ybS1maWVsZCBjbGFzcz0iZXhhbXBsZS1mdWxsLXdpZHRoIj4KICAgIDxtYXQtbGFiZWw+RW50ZXIgcG9zdCBjb250ZW50PC9tYXQtbGFiZWw+CiAgICA8dGV4dGFyZWEgbWF0SW5wdXQgcGxhY2Vob2xkZXI9IlBvc3RTZXJ2aWNlIGNvbnRlbnQiIGZvcm1Db250cm9sTmFtZT0icG9zdENvbnRlbnQiPjwvdGV4dGFyZWE+CiAgPC9tYXQtZm9ybS1maWVsZD4KCiAgPGRpdj4KICAgIDxidXR0b24gW2Rpc2FibGVkXT0iZm9ybS5pbnZhbGlkIiBtYXRCdXR0b249ImZpbGxlZCI+U2F2ZTwvYnV0dG9uPgogIDwvZGl2Pgo8L2Zvcm0+Cg==&#8221; copy_button=&#8221;on&#8221; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_dmb_code_snippet][et_pb_comments _builder_version=&#8221;4.21.2&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_comments][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this video, we\u2019ll see how to add custom sync and async validators in an Angular application, and also how to handle Observable unsubscription.First, we will add an Observable unsubscription mechanism. This is useful in any application to avoid memory leaks. In modern Angular, there is a takeUntilDestroyed() operator. It takes an instance of the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[256,219],"tags":[],"class_list":["post-36807","post","type-post","status-publish","format-standard","hentry","category-javascript","category-tutorials"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Create custom validators in Angular application - Kamil Abzalov&#039;s site<\/title>\n<meta name=\"description\" content=\"Learn how to create custom validators in Angular to handle complex data validation. Step-by-step guide on implementing Synchronous and Asynchronous validators with code examples and best practices\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create custom validators in Angular application\" \/>\n<meta property=\"og:description\" content=\"Learn how to create custom validators in Angular to handle complex data validation. Step-by-step guide on implementing Synchronous and Asynchronous validators with code examples and best practices\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/\" \/>\n<meta property=\"og:site_name\" content=\"\u0441\u0430\u0439\u0442 \u041a\u0430\u043c\u0438\u043b\u044f \u0410\u0431\u0437\u0430\u043b\u043e\u0432\u0430\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/kamabzalov\" \/>\n<meta property=\"article:published_time\" content=\"2026-04-18T18:49:08+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-18T19:03:46+00:00\" \/>\n<meta name=\"author\" content=\"Kamil&#039; Abzalov\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@kamabzalov\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Kamil&#039; Abzalov\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/en\\\/tutorials\\\/javascript\\\/create-custom-validators-in-angular-application\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/en\\\/tutorials\\\/javascript\\\/create-custom-validators-in-angular-application\\\/\"},\"author\":{\"name\":\"Kamil' Abzalov\",\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/#\\\/schema\\\/person\\\/9c53360f21b83306ba40c2231573c600\"},\"headline\":\"Create custom validators in Angular application\",\"datePublished\":\"2026-04-18T18:49:08+00:00\",\"dateModified\":\"2026-04-18T19:03:46+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/en\\\/tutorials\\\/javascript\\\/create-custom-validators-in-angular-application\\\/\"},\"wordCount\":2139,\"commentCount\":0,\"articleSection\":[\"JavaScript\",\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/kamil-abzalov.com\\\/en\\\/tutorials\\\/javascript\\\/create-custom-validators-in-angular-application\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/en\\\/tutorials\\\/javascript\\\/create-custom-validators-in-angular-application\\\/\",\"url\":\"https:\\\/\\\/kamil-abzalov.com\\\/en\\\/tutorials\\\/javascript\\\/create-custom-validators-in-angular-application\\\/\",\"name\":\"Create custom validators in Angular application - Kamil Abzalov's site\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/#website\"},\"datePublished\":\"2026-04-18T18:49:08+00:00\",\"dateModified\":\"2026-04-18T19:03:46+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/#\\\/schema\\\/person\\\/9c53360f21b83306ba40c2231573c600\"},\"description\":\"Learn how to create custom validators in Angular to handle complex data validation. Step-by-step guide on implementing Synchronous and Asynchronous validators with code examples and best practices\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/en\\\/tutorials\\\/javascript\\\/create-custom-validators-in-angular-application\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/kamil-abzalov.com\\\/en\\\/tutorials\\\/javascript\\\/create-custom-validators-in-angular-application\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/en\\\/tutorials\\\/javascript\\\/create-custom-validators-in-angular-application\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\",\"item\":\"https:\\\/\\\/kamil-abzalov.com\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create custom validators in Angular application\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/#website\",\"url\":\"https:\\\/\\\/kamil-abzalov.com\\\/\",\"name\":\"\u0441\u0430\u0439\u0442 \u041a\u0430\u043c\u0438\u043b\u044f \u0410\u0431\u0437\u0430\u043b\u043e\u0432\u0430\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/kamil-abzalov.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/kamil-abzalov.com\\\/#\\\/schema\\\/person\\\/9c53360f21b83306ba40c2231573c600\",\"name\":\"Kamil' Abzalov\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3ad2daebcb3a4d03f8573b49054a003cd26a151ecc58ccfccc75b823131d1ead?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3ad2daebcb3a4d03f8573b49054a003cd26a151ecc58ccfccc75b823131d1ead?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3ad2daebcb3a4d03f8573b49054a003cd26a151ecc58ccfccc75b823131d1ead?s=96&d=mm&r=g\",\"caption\":\"Kamil' Abzalov\"},\"sameAs\":[\"https:\\\/\\\/kamil-abzalov.com\\\/\",\"https:\\\/\\\/www.facebook.com\\\/kamabzalov\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/kamabzalov\",\"https:\\\/\\\/x.com\\\/kamabzalov\",\"https:\\\/\\\/www.youtube.com\\\/user\\\/kamabzalov\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Create custom validators in Angular application - Kamil Abzalov's site","description":"Learn how to create custom validators in Angular to handle complex data validation. Step-by-step guide on implementing Synchronous and Asynchronous validators with code examples and best practices","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/","og_locale":"en_US","og_type":"article","og_title":"Create custom validators in Angular application","og_description":"Learn how to create custom validators in Angular to handle complex data validation. Step-by-step guide on implementing Synchronous and Asynchronous validators with code examples and best practices","og_url":"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/","og_site_name":"\u0441\u0430\u0439\u0442 \u041a\u0430\u043c\u0438\u043b\u044f \u0410\u0431\u0437\u0430\u043b\u043e\u0432\u0430","article_author":"https:\/\/www.facebook.com\/kamabzalov","article_published_time":"2026-04-18T18:49:08+00:00","article_modified_time":"2026-04-18T19:03:46+00:00","author":"Kamil' Abzalov","twitter_card":"summary_large_image","twitter_creator":"@kamabzalov","twitter_misc":{"Written by":"Kamil' Abzalov","Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/#article","isPartOf":{"@id":"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/"},"author":{"name":"Kamil' Abzalov","@id":"https:\/\/kamil-abzalov.com\/#\/schema\/person\/9c53360f21b83306ba40c2231573c600"},"headline":"Create custom validators in Angular application","datePublished":"2026-04-18T18:49:08+00:00","dateModified":"2026-04-18T19:03:46+00:00","mainEntityOfPage":{"@id":"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/"},"wordCount":2139,"commentCount":0,"articleSection":["JavaScript","Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/","url":"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/","name":"Create custom validators in Angular application - Kamil Abzalov's site","isPartOf":{"@id":"https:\/\/kamil-abzalov.com\/#website"},"datePublished":"2026-04-18T18:49:08+00:00","dateModified":"2026-04-18T19:03:46+00:00","author":{"@id":"https:\/\/kamil-abzalov.com\/#\/schema\/person\/9c53360f21b83306ba40c2231573c600"},"description":"Learn how to create custom validators in Angular to handle complex data validation. Step-by-step guide on implementing Synchronous and Asynchronous validators with code examples and best practices","breadcrumb":{"@id":"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/kamil-abzalov.com\/en\/tutorials\/javascript\/create-custom-validators-in-angular-application\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430","item":"https:\/\/kamil-abzalov.com\/en\/"},{"@type":"ListItem","position":2,"name":"Create custom validators in Angular application"}]},{"@type":"WebSite","@id":"https:\/\/kamil-abzalov.com\/#website","url":"https:\/\/kamil-abzalov.com\/","name":"\u0441\u0430\u0439\u0442 \u041a\u0430\u043c\u0438\u043b\u044f \u0410\u0431\u0437\u0430\u043b\u043e\u0432\u0430","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kamil-abzalov.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/kamil-abzalov.com\/#\/schema\/person\/9c53360f21b83306ba40c2231573c600","name":"Kamil' Abzalov","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/3ad2daebcb3a4d03f8573b49054a003cd26a151ecc58ccfccc75b823131d1ead?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/3ad2daebcb3a4d03f8573b49054a003cd26a151ecc58ccfccc75b823131d1ead?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3ad2daebcb3a4d03f8573b49054a003cd26a151ecc58ccfccc75b823131d1ead?s=96&d=mm&r=g","caption":"Kamil' Abzalov"},"sameAs":["https:\/\/kamil-abzalov.com\/","https:\/\/www.facebook.com\/kamabzalov","https:\/\/www.linkedin.com\/in\/kamabzalov","https:\/\/x.com\/kamabzalov","https:\/\/www.youtube.com\/user\/kamabzalov"]}]}},"_links":{"self":[{"href":"https:\/\/kamil-abzalov.com\/en\/wp-json\/wp\/v2\/posts\/36807","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kamil-abzalov.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kamil-abzalov.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kamil-abzalov.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kamil-abzalov.com\/en\/wp-json\/wp\/v2\/comments?post=36807"}],"version-history":[{"count":8,"href":"https:\/\/kamil-abzalov.com\/en\/wp-json\/wp\/v2\/posts\/36807\/revisions"}],"predecessor-version":[{"id":36821,"href":"https:\/\/kamil-abzalov.com\/en\/wp-json\/wp\/v2\/posts\/36807\/revisions\/36821"}],"wp:attachment":[{"href":"https:\/\/kamil-abzalov.com\/en\/wp-json\/wp\/v2\/media?parent=36807"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kamil-abzalov.com\/en\/wp-json\/wp\/v2\/categories?post=36807"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kamil-abzalov.com\/en\/wp-json\/wp\/v2\/tags?post=36807"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}