{"id":28479,"date":"2021-07-05T12:43:09","date_gmt":"2021-07-05T12:43:09","guid":{"rendered":"https:\/\/www.inogic.com\/blog\/?p=28479"},"modified":"2022-01-21T10:17:27","modified_gmt":"2022-01-21T04:47:27","slug":"get-quick-details-on-new-async-onsave-event-in-dynamics-365-crm","status":"publish","type":"post","link":"https:\/\/www.inogic.com\/blog\/2021\/07\/get-quick-details-on-new-async-onsave-event-in-dynamics-365-crm\/","title":{"rendered":"Get Quick details on new Async OnSave Event in Dynamics 365 CRM"},"content":{"rendered":"<h3 style=\"text-align: justify;\">Introduction:<\/h3>\n<p style=\"text-align: justify;\">I am sure you may have used OnSave event several times in your projects. We generally use this event and write code in it to do some validation on record to restrict the user from saving the record (using prevenDefaults method).<\/p>\n<p style=\"text-align: justify;\">The nature of OnSave event is synchronous. It is not right to call it asynchronous code because it does wait for it and we may see unsaved changes. If we make synchronous network request in OnSave event, it can cause slow experience and unresponsive page.<\/p>\n<p style=\"text-align: justify;\">Microsoft has introduced a new aysnc OnSave event. This event is called after save event is complete and it supports after\u00a0Save\u00a0actions when the\u00a0save\u00a0event is successful or failed. There is also a new timeout if the promise does not resolve within 10 seconds. If it does not resolve within 10 seconds, the save operation will be blocked.<\/p>\n<p style=\"text-align: justify;\">We will see how this async event is useful over save event. To enable this feature we need to create one record in Model driven app settings.<\/p>\n<p style=\"text-align: justify;\">To enable the AsyncOnSave for a specific app, add the below XML in the\u00a0customization.xml\u00a0file. This should be added in the existing App Module node in your\u00a0customization.xml\u00a0file.<\/p>\n<p style=\"text-align: justify;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0Setting the\u00a0&lt;value&gt;true&lt;\/value&gt;\u00a0enables AsyncOnSave support for that specific app.<\/p>\n<pre class=\"lang:css gutter:true start:1\">&lt;appsettings&gt;\r\n&lt;appsetting uniquename=\"CRMHub_SalesApp_AsyncOnSave\"&gt;\r\n&lt;iscustomizable&gt;1&lt;\/iscustomizable&gt;\r\n&lt;settingdefinitionid&gt;\r\n&lt;uniquename&gt;AsyncOnSave&lt;\/uniquename&gt;\r\n&lt;\/settingdefinitionid&gt;\r\n&lt;value&gt;true&lt;\/value&gt;\r\n&lt;\/appsetting&gt;\r\n&lt;\/appsettings&gt;\r\n<\/pre>\n<p style=\"text-align: justify;\">Import this into Dynamics 365 CRM.<\/p>\n<p style=\"text-align: justify;\">Once appsettings is added, you can check whether the feature is enabled or not, as shown below \u2013 (Value should be True).<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/1-Async-onsave-event.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"aligncenter wp-image-28483 size-full\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/1-Async-onsave-event-e1625470341466.png\" alt=\"Async onsave event Dynamics 365\" width=\"981\" height=\"792\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/1-Async-onsave-event-e1625470341466.png 981w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/1-Async-onsave-event-e1625470341466-300x242.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/1-Async-onsave-event-e1625470341466-768x620.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/1-Async-onsave-event-e1625470341466-660x533.png 660w\" sizes=\"(max-width: 981px) 100vw, 981px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><strong>Now, given below is the code for Async on save \u2013<\/strong><\/p>\n<pre class=\"lang:css gutter:true start:1\">onLoad(executionContext): void {\u00a0 \u00a0 \r\nlet functionName: string = \"onLoad\";\r\ntry {\r\nlet formContext = executionContext.getFormContext();\r\nformContext.data.entity.addOnSave(\r\n(() =&gt; {\r\nreturn async (context) =&gt; {\r\ncontext.getEventArgs().preventDefaultOnError();\r\nawait AfterSaveAsyncMethod(context);\r\n}\r\n}\r\n)());\r\nvar AfterSaveAsyncMethod = (context) =&gt; {\r\nreturn new Promise((resolve, reject) =&gt; {\r\nXrm.WebApi.retrieveMultipleRecords(\"contact\", \"?$select=fullname&amp;$filter= emailaddress1 like '%gmail.com%'\")\r\n.then(function (result) {\r\nif (result.entities.length&gt;0) {\r\nresolve(true);\r\n}\r\nelse {\r\nreject(\"error\");\r\n}\r\n});\r\n});\r\n}\r\n}\r\ncatch (ex) {\r\nXrm.Navigation.openErrorDialog(ex.message).then(\r\nfunction (success) {\r\nconsole.log(success);\r\n},\r\nfunction (error) {\r\nconsole.log(error);\r\n});\r\n}\r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\">In the above code, you can see that I have registered the save event on a load of form. The OnSave event can now accept promises. And when you return a promise inside your method registered on save of the form, it becomes async.<\/p>\n<p style=\"text-align: justify;\">I have called <strong>Xrm.WebApi.retrieveMultipleRecords<\/strong> which is async method, because of which save event will wait until retrieve is completed. Here, to cancel the save operation, I tried to use executionContext.getEventArgs().prevenDefault(). But this did not work because Microsoft has added Context.getEventArgs().preventDefaultOnError() method for async OnSave restriction.<\/p>\n<p style=\"text-align: justify;\">You will get the below error if promise didn\u2019t return within 10 seconds \u2013<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/2-Async-onsave-event-1.png\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" class=\"aligncenter wp-image-28485 size-full\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/2-Async-onsave-event-1.png\" alt=\"Async onsave event Dynamics 365\" width=\"1189\" height=\"812\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/2-Async-onsave-event-1.png 1189w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/2-Async-onsave-event-1-300x205.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/2-Async-onsave-event-1-768x524.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/2-Async-onsave-event-1-1024x699.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2021\/07\/2-Async-onsave-event-1-660x451.png 660w\" sizes=\"(max-width: 1189px) 100vw, 1189px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">One more thing I want to highlight is if Context.getEventArgs().preventDefaultOnError()\u00a0 method is called, then the Async OnSave event will still wait for all the promises to settle, but the save will not occur. This means the logic in it will still execute successcallback and errorcallback.<\/p>\n<h3 style=\"text-align: justify;\"><strong>Conclusion: <\/strong><\/h3>\n<p style=\"text-align: justify;\">In this way, you can easily use the Async OnSave event in Dynamics 365 CRM.<\/p>\n<p style=\"text-align: left;\">Reference Link: <a href=\"https:\/\/docs.microsoft.com\/en-us\/powerapps\/developer\/model-driven-apps\/clientapi\/reference\/events\/form-onsave\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/docs.microsoft.com\/en-us\/powerapps\/developer\/model-driven-apps\/clientapi\/reference\/events\/form-onsave<\/a><\/p>\n<h2 style=\"text-align: left;\"><div class=\"su-heading su-heading-style-default su-heading-align-center\" id=\"\" style=\"font-size:15px;margin-bottom:5px\"><div class=\"su-heading-inner\">One Pic = 1000 words! Analyze data 90% faster with visualization apps!<\/div><\/div><\/h2>\n<p style=\"text-align: left;\"><em>Get optimum visualization of Dynamics 365 CRM data with &#8211;<\/em><br \/>\n<em><strong><a href=\"https:\/\/bit.ly\/3lYvozZ\" target=\"_blank\" rel=\"noopener noreferrer\">Kanban Board<\/a> <\/strong>\u2013 Visualize Dynamics 365 CRM data in Kanban view by categorizing entity records in lanes and rows as per their status, priority, etc.<\/em><br \/>\n<em><strong><a href=\"https:\/\/bit.ly\/3lCSBaA\" target=\"_blank\" rel=\"noopener noreferrer\">Map My Relationships<\/a><\/strong> \u2013 Map My Relationships \u2013 Visualize connections and relationships between Dynamics 365 CRM entities or related records in a Mind Map view.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction: I am sure you may have used OnSave event several times in your projects. We generally use this event and write code in it to do some validation on record to restrict the user from saving the record (using prevenDefaults method). The nature of OnSave event is synchronous. It is not right to call\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.inogic.com\/blog\/2021\/07\/get-quick-details-on-new-async-onsave-event-in-dynamics-365-crm\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":13,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[16,19],"tags":[2250,545],"class_list":["post-28479","post","type-post","status-publish","format-standard","hentry","category-dynamics-365","category-dynamics-crm","tag-async-onsave-events","tag-dynamics-365-crm"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/28479","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/comments?post=28479"}],"version-history":[{"count":0,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/28479\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/media?parent=28479"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/categories?post=28479"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/tags?post=28479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}