{"id":1283,"date":"2017-10-26T14:09:57","date_gmt":"2017-10-26T12:09:57","guid":{"rendered":"https:\/\/blog.thecodecampus.de\/?p=1283"},"modified":"2023-12-20T19:49:45","modified_gmt":"2023-12-20T18:49:45","slug":"angular-serverside-validation","status":"publish","type":"post","link":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/","title":{"rendered":"Angular Serverside Validation with Hibernate and Redux"},"content":{"rendered":"<h2><a href=\"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/10\/BO__5321_low_res.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-1298\" src=\"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/10\/BO__5321_low_res-1024x682.jpg\" alt=\"\" width=\"1024\" height=\"682\" srcset=\"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/10\/BO__5321_low_res-1024x682.jpg 1024w, https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/10\/BO__5321_low_res-300x200.jpg 300w, https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/10\/BO__5321_low_res-768x512.jpg 768w, https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2017\/10\/BO__5321_low_res.jpg 1499w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/h2>\n<h1>What is this article about?<\/h1>\n<p>If you develop a web application with Angular, sooner or later you will run into the following problem: <strong>Where will the data generated by the client be validated<\/strong>? Client side validation is included in Angular, and gives the user a fast feedback about the correctness of his data. This is a standard in today&#8217;s web application.<\/p>\n<p>As most Angular Apps are running against a server side REST Interface the data has to be validated again on the server to guarantee the correctness of the data.\u00a0Otherwise, incorrect data could be inserted into the database.<\/p>\n<p><strong>The problem is, how to avoid duplicating the validation logic in the client and the server. I want to show you an approach we chose, and which works fine in an intranet application we recently deployed.<br \/>\n<\/strong><\/p>\n<h1>Our simple approach to serverside validation with Angular<\/h1>\n<p>Since the application runs on an intranet &#8211; and thus it is ensured that an additional network roundtrip does not have a negative influence on the client&#8217;s reactivity &#8211; we decided to carry out the validation logic completely to server. Our ORM framework (Hibernate) has a validation feature that we were able to utilize for this.\u00a0The advantage is obvious: the validation logic only needs to be implemented once.<\/p>\n<p>However, this creates the challenge of transferring the validation results from the server back to the client. As the user types we call the validation endpoint frequently and update the forms error state in order to inform both, the user and the Angular application.<\/p>\n<h2>Deciding how to call the Validation API<\/h2>\n<p>Our first approach was to listen to the respective Angular Input Controls and send the data to server.The code for this would more or less like this:<\/p>\n<pre class=\"lang:default decode:true\">nameControl.valueChanges.forEach(\r\n    (value: string) =&gt; this.nameChangeLog.push(value)\r\n  );<\/pre>\n<p>But this approach had several drawbacks:<\/p>\n<ol>\n<li>Since our entity is spread over several forms, we would have to collect the different subsets of the entity and send them back to the server as a complete entity.<\/li>\n<li>It is hard to decide how often and when to send the data to the server. When the users exits a control (onBlur) or after each keystroke?<\/li>\n<\/ol>\n<h2>The Redux way<\/h2>\n<p>As we already have a Redux store backing all our forms we decided to trigger the validation from a Redux Effect. The code is shown below. Basically it sends the full data obejct every 300ms (but only when changes are made) to the server.<\/p>\n<pre class=\"lang:default decode:true \">@Effect()\r\nvalidate: Observable&lt;Action&gt; = this.actions$\r\n  \/\/Register the types to run the effect on\r\n  .ofType(UPDATE_FORM)\r\n  \/\/debounce for 300ms, so we do not send on every keystroke\r\n  .debounceTime(300)\r\n  .map(toPayload)\r\n  \/\/ retrieve our full data object from the store\r\n  .switchMap((something) =&gt; {\r\n\t return this.store.select(getSaveableObject).first();\r\n  })\r\n  .switchMap(val =&gt; {\r\n     const data = val.data;\r\n     \/\/call the serverside validation service\r\n     return this.service.validate(data).map(errors =&gt; {\r\n        \/\/take all the errors and go on\r\n\treturn new UpdateErrorsAction(errors);\r\n     });\r\n  }).catch(() =&gt; Observable.of(new UpdateErrorsAction(null)));<\/pre>\n<h2>On the Server<\/h2>\n<p>On the server we are validating our data object by using JavaEE Bean Validation and some custom code. JavaEE Bean Validation has some nice Annotations to check fields. Further information can be found <a href=\"http:\/\/beanvalidation.org\/\">here<\/a>. The code displayed here is in Kotlin, but this could be easily done with Java too.<\/p>\n<pre class=\"\">import javax.validation.Validation\r\nimport javax.validation.Validator<\/pre>\n<pre class=\"lang:java decode:true\">\/\/ run the validation \r\nval constraintViolations = Validation.buildDefaultValidatorFactory().validator!!.validate(entity) \r\n\/\/ map the validations to key value pairs, in order to send them to the client \r\nval controlErrors = constraintViolations.associateBy({ it.propertyPath.toString() }, { it.message })<\/pre>\n<p>Note: We also have some custom validation, which runs logic checks against the given data object and writes the errors into a Simple Java Map.<\/p>\n<h2>Displaying Errors in the Client<\/h2>\n<p>In the client, we perform the following operations each time the server answers a validation request.<\/p>\n<ol>\n<li>Set the error state via Angular<\/li>\n<li>Disable the save button<\/li>\n<\/ol>\n<h3>Setting errors<\/h3>\n<p>The first snippet demonstrates how to set an error to an Angular control. It is very important (at least for Angular Material) to mark the control as touched. Otherwise the error will not be displayed.<\/p>\n<pre class=\"lang:js decode:true\">const control = form.controls[key];\r\ncontrol.setErrors({\"serverValidationErr\": errorText});\r\ncontrol.markAsTouched();<\/pre>\n<p>To display the error text, the following snippet is also needed for every input control.<\/p>\n<pre class=\"lang:default decode:true\">&lt;md-error *ngIf=\"form.controls.fieldName.hasError('serverValidationErr')\"&gt;                                    \r\n  {{form.controls.auftragNummer.errors.serverValidationErr}}\r\n&lt;\/md-error&gt;<\/pre>\n<p><strong>To summarize what we achieved:\u00a0A validation that only had to be implemented once and still applies to the server and client.\u00a0This allows us an agile further development.<\/strong><\/p>\n<h1>Conclusion<\/h1>\n<p>The approach really worked very well for our application. We only have to write validation logic once on the server. The data is validated every 300ms and also on saving. Of course there is a lot more to do, then displayed here. Matching the error Map which is sent from the server to the client can be quit difficult, especially when there is data in collections involeved. This snippet is some code which matches errors to forms which are in a collection.<\/p>\n<pre class=\"lang:js decode:true\">addErrorToFormFromCollection(form: FormGroup, key: string, selectedIndex: number, errorText: string) {\r\n\t    let errorIndexTest = key.match(\/\\[(.*?)\\]\/);\r\n\t\r\n\t    if (errorIndexTest) {\r\n\t      let errorIndex = errorIndexTest[1];\r\n\t      \/\/ this.logger.info(errorIndex);\r\n\t\r\n\t      if (selectedIndex.toString() == errorIndex) {\r\n\t        \/\/ this.logger.info(\"matches\");\r\n\t\r\n\t        const posOfDot = key.indexOf('.');\r\n\t        const fieldName = key.slice(posOfDot + 1, key.length);\r\n\t        \/\/ this.logger.info(fieldName);\r\n\t\r\n\t        this.addErrorToForm(form, fieldName, errorText);\r\n\t      }\r\n\t    }\r\n\t  };<\/pre>\n<h2>Intranet-Only<\/h2>\n<p>This approach suits only intranet applications, where there is a quite fast bandwidth. Depending on the size of the dataobject there is quite a lot of data sent over the network.<\/p>\n<p><strong>We never experienced any problems in our environment.<\/strong><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What is this article about? If you develop a web application with Angular, sooner or later you will run into the following problem: Where will the data generated by the client be validated? Client side validation is included in Angular, and gives the user a fast feedback about the correctness of his data. This is [&#8230;]<br \/><a class=\"meta-big\" href=\"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/\"> READ MORE<\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[73,96,41,95],"tags":[],"class_list":["post-1283","post","type-post","status-publish","format-standard","hentry","category-angular","category-hibernate","category-java","category-validation"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Angular Serverside Validation with Hibernate and Redux - Web Development Blog<\/title>\n<meta name=\"description\" content=\"Explore Server-side Validation with Hibernate in our Angular Intranet App guide. Write validation logic once, unlock multiple benefits! Dive in now!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular Serverside Validation with Hibernate and Redux - Web Development Blog\" \/>\n<meta property=\"og:description\" content=\"Explore Server-side Validation with Hibernate in our Angular Intranet App guide. Write validation logic once, unlock multiple benefits! Dive in now!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Development tips and tricks - theCodeCampus Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-10-26T12:09:57+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-20T18:49:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/10\/BO__5321_low_res-1024x682.jpg\" \/>\n<meta name=\"author\" content=\"Jan Blankenhorn\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jan Blankenhorn\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"4\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/\"},\"author\":{\"name\":\"Jan Blankenhorn\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#\\\/schema\\\/person\\\/623acdcedf59e3d9d86df17721a46188\"},\"headline\":\"Angular Serverside Validation with Hibernate and Redux\",\"datePublished\":\"2017-10-26T12:09:57+00:00\",\"dateModified\":\"2023-12-20T18:49:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/\"},\"wordCount\":724,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blog.thecodecampus.de\\\/wp-content\\\/uploads\\\/2017\\\/10\\\/BO__5321_low_res-1024x682.jpg\",\"articleSection\":[\"Angular\",\"Hibernate\",\"Java\",\"Validation\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/\",\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/\",\"name\":\"Angular Serverside Validation with Hibernate and Redux - Web Development Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blog.thecodecampus.de\\\/wp-content\\\/uploads\\\/2017\\\/10\\\/BO__5321_low_res-1024x682.jpg\",\"datePublished\":\"2017-10-26T12:09:57+00:00\",\"dateModified\":\"2023-12-20T18:49:45+00:00\",\"description\":\"Explore Server-side Validation with Hibernate in our Angular Intranet App guide. Write validation logic once, unlock multiple benefits! Dive in now!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/#primaryimage\",\"url\":\"https:\\\/\\\/blog.thecodecampus.de\\\/wp-content\\\/uploads\\\/2017\\\/10\\\/BO__5321_low_res-1024x682.jpg\",\"contentUrl\":\"https:\\\/\\\/blog.thecodecampus.de\\\/wp-content\\\/uploads\\\/2017\\\/10\\\/BO__5321_low_res-1024x682.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/angular-serverside-validation\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular Serverside Validation with Hibernate and Redux\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/\",\"name\":\"Web Development tips and tricks - theCodeCampus Blog\",\"description\":\"Tips, tricks, and experiences about developing web and mobile applications with Angular, TypeScript, and Testing.\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#organization\",\"name\":\"theCodeCampus\",\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/01\\\/TCC-Logo-Bildmarke-quadratisch.jpg\",\"contentUrl\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/01\\\/TCC-Logo-Bildmarke-quadratisch.jpg\",\"width\":156,\"height\":156,\"caption\":\"theCodeCampus\"},\"image\":{\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/#\\\/schema\\\/person\\\/623acdcedf59e3d9d86df17721a46188\",\"name\":\"Jan Blankenhorn\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/06\\\/jan-blankenhorn-tcc-author-96x96.webp\",\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/06\\\/jan-blankenhorn-tcc-author-96x96.webp\",\"contentUrl\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/06\\\/jan-blankenhorn-tcc-author-96x96.webp\",\"caption\":\"Jan Blankenhorn\"},\"description\":\"Jan Blankenhorn brings over 15 years of experience as a developer and trainer, specializing in web development with Angular. He enjoys engaging with people and shares practical examples in his training sessions with a touch of humor.\",\"sameAs\":[\"https:\\\/\\\/thecodecampus.de\\\/ueber-uns\\\/trainer\\\/jan-blankenhorn\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/jan-blankenhorn-w11k\\\/\"],\"url\":\"https:\\\/\\\/www.thecodecampus.de\\\/blog\\\/author\\\/jblankenhorn\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Angular Serverside Validation with Hibernate and Redux - Web Development Blog","description":"Explore Server-side Validation with Hibernate in our Angular Intranet App guide. Write validation logic once, unlock multiple benefits! Dive in now!","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:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/","og_locale":"de_DE","og_type":"article","og_title":"Angular Serverside Validation with Hibernate and Redux - Web Development Blog","og_description":"Explore Server-side Validation with Hibernate in our Angular Intranet App guide. Write validation logic once, unlock multiple benefits! Dive in now!","og_url":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/","og_site_name":"Web Development tips and tricks - theCodeCampus Blog","article_published_time":"2017-10-26T12:09:57+00:00","article_modified_time":"2023-12-20T18:49:45+00:00","og_image":[{"url":"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/10\/BO__5321_low_res-1024x682.jpg","type":"","width":"","height":""}],"author":"Jan Blankenhorn","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Jan Blankenhorn","Gesch\u00e4tzte Lesezeit":"4\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/#article","isPartOf":{"@id":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/"},"author":{"name":"Jan Blankenhorn","@id":"https:\/\/www.thecodecampus.de\/blog\/#\/schema\/person\/623acdcedf59e3d9d86df17721a46188"},"headline":"Angular Serverside Validation with Hibernate and Redux","datePublished":"2017-10-26T12:09:57+00:00","dateModified":"2023-12-20T18:49:45+00:00","mainEntityOfPage":{"@id":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/"},"wordCount":724,"commentCount":1,"publisher":{"@id":"https:\/\/www.thecodecampus.de\/blog\/#organization"},"image":{"@id":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/10\/BO__5321_low_res-1024x682.jpg","articleSection":["Angular","Hibernate","Java","Validation"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/","url":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/","name":"Angular Serverside Validation with Hibernate and Redux - Web Development Blog","isPartOf":{"@id":"https:\/\/www.thecodecampus.de\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/#primaryimage"},"image":{"@id":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/10\/BO__5321_low_res-1024x682.jpg","datePublished":"2017-10-26T12:09:57+00:00","dateModified":"2023-12-20T18:49:45+00:00","description":"Explore Server-side Validation with Hibernate in our Angular Intranet App guide. Write validation logic once, unlock multiple benefits! Dive in now!","breadcrumb":{"@id":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/#primaryimage","url":"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/10\/BO__5321_low_res-1024x682.jpg","contentUrl":"https:\/\/blog.thecodecampus.de\/wp-content\/uploads\/2017\/10\/BO__5321_low_res-1024x682.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/www.thecodecampus.de\/blog\/angular-serverside-validation\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.thecodecampus.de\/blog\/"},{"@type":"ListItem","position":2,"name":"Angular Serverside Validation with Hibernate and Redux"}]},{"@type":"WebSite","@id":"https:\/\/www.thecodecampus.de\/blog\/#website","url":"https:\/\/www.thecodecampus.de\/blog\/","name":"Web Development tips and tricks - theCodeCampus Blog","description":"Tips, tricks, and experiences about developing web and mobile applications with Angular, TypeScript, and Testing.","publisher":{"@id":"https:\/\/www.thecodecampus.de\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.thecodecampus.de\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/www.thecodecampus.de\/blog\/#organization","name":"theCodeCampus","url":"https:\/\/www.thecodecampus.de\/blog\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.thecodecampus.de\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2024\/01\/TCC-Logo-Bildmarke-quadratisch.jpg","contentUrl":"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2024\/01\/TCC-Logo-Bildmarke-quadratisch.jpg","width":156,"height":156,"caption":"theCodeCampus"},"image":{"@id":"https:\/\/www.thecodecampus.de\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.thecodecampus.de\/blog\/#\/schema\/person\/623acdcedf59e3d9d86df17721a46188","name":"Jan Blankenhorn","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2024\/06\/jan-blankenhorn-tcc-author-96x96.webp","url":"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2024\/06\/jan-blankenhorn-tcc-author-96x96.webp","contentUrl":"https:\/\/www.thecodecampus.de\/blog\/wp-content\/uploads\/2024\/06\/jan-blankenhorn-tcc-author-96x96.webp","caption":"Jan Blankenhorn"},"description":"Jan Blankenhorn brings over 15 years of experience as a developer and trainer, specializing in web development with Angular. He enjoys engaging with people and shares practical examples in his training sessions with a touch of humor.","sameAs":["https:\/\/thecodecampus.de\/ueber-uns\/trainer\/jan-blankenhorn","https:\/\/www.linkedin.com\/in\/jan-blankenhorn-w11k\/"],"url":"https:\/\/www.thecodecampus.de\/blog\/author\/jblankenhorn\/"}]}},"_links":{"self":[{"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/posts\/1283","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/comments?post=1283"}],"version-history":[{"count":14,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/posts\/1283\/revisions"}],"predecessor-version":[{"id":1301,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/posts\/1283\/revisions\/1301"}],"wp:attachment":[{"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/media?parent=1283"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/categories?post=1283"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.thecodecampus.de\/blog\/wp-json\/wp\/v2\/tags?post=1283"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}