{"id":33310,"date":"2022-12-09T16:17:19","date_gmt":"2022-12-09T10:47:19","guid":{"rendered":"https:\/\/www.inogic.com\/blog\/?p=33310"},"modified":"2022-12-19T12:04:54","modified_gmt":"2022-12-19T06:34:54","slug":"use-of-async-await-in-virtual-pcf-control","status":"publish","type":"post","link":"https:\/\/www.inogic.com\/blog\/2022\/12\/use-of-async-await-in-virtual-pcf-control\/","title":{"rendered":"Use of async-await in virtual PCF control"},"content":{"rendered":"<p>Recently while working on the virtual PCF control we noticed that the <strong>updateView()<\/strong> in the virtual PCF works in a different manner as compared to standard PCF control with async functions. In standard PCF control, the return type of the <strong>updateView()<\/strong> is void while in the virtual PCF the return type is react-element. So when we return the promise to the <strong>updateView()<\/strong> by calling the callback function in a virtual PCF control, we do not get the desired result.<\/p>\n<p>Let&#8217;s take an example where we will create a virtual drop-down PCF control. We will be showing the entity attributes as options in our drop-down control. In the example below, we have created an async function\u00a0\u00a0 GetEntityAttribute which will be responsible for getting the entity attributes to list out in our PCF drop-down control.<\/p>\n<p>If we call our async function GetEntityAttribute in the updateView() as follows, we will not get the options with dropdown as shown in the below image.<\/p>\n<p><strong>UpdateView() Then:<\/strong><\/p>\n<p>public updateView(context: ComponentFramework.Context&lt;IInputs&gt;): React.ReactElement {<\/p>\n<pre class=\"lang:css gutter:true start:1\">\/\/Local variables\r\n\r\nlet isDisable: boolean = false;\r\n\r\nlet isMultiple: boolean = false;\r\n\r\nlet dropDownProps: any;\r\n\r\n\/\/Calling function to get the attributes\r\n\r\nthis.GetEntityAttribute(context);\r\n\r\n\u00a0\r\n\r\n\/\/Calling function to get the selected values\r\n\r\nthis.selectedItem = this.getSelecetdItems(context)\r\n\r\ndropDownProps = {\r\n\r\nentityMetadata: this.entityAttributes,\r\n\r\ndefaultSelectedOptions: this.selectedItem,\r\n\r\nisMultiple: isMultiple,\r\n\r\nisDisable: isDisable,\r\n\r\nnotifyChange: this.notifyChange.bind(this),\r\n\r\ncontext: context\r\n\r\n};\r\n\r\nreturn React.createElement(\r\n\r\nDynamicDropdown, dropDownProps\r\n\r\n);\r\n\r\n}<\/pre>\n<p>Field Interface then:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-33312\" style=\"border: 1px solid #0a0a0a; padding: 1px; margin: 1px;\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/1virtual-PCF-control.jpeg\" alt=\"virtual PCF control\" width=\"511\" height=\"250\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/1virtual-PCF-control.jpeg 511w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/1virtual-PCF-control-300x147.jpeg 300w\" sizes=\"(max-width: 511px) 100vw, 511px\" \/><\/p>\n<p>It happens because when an async function is called and executed the program control directly jumps to the next line of the updateView() and executes it first and renders a dropdown control with no options. It then goes again to the async function to execute the code after await where we had our array of all attributes. Since the control was rendered already, we will not get a drop-down with options.<\/p>\n<p>To solve this issue we will use the <strong>useEffect()<\/strong> function of the react and call async functions inside it rather than calling the async function in the updateView(). Thus, the updateView() will now look as follows.<\/p>\n<p><strong>UpdateView() Now:<\/strong><\/p>\n<pre class=\"lang:css gutter:true start:1\">public updateView(context: ComponentFramework.Context&lt;IInputs&gt;): React.ReactElement {\r\n\r\n\/\/Local variables\r\n\r\nlet isDisable: boolean = false;\r\n\r\nlet isMultiple: boolean = false;\r\n\r\nlet dropDownProps: IDynamicDropdownProps = {};\r\n\r\nlet entityName: string | null = \"\";\r\n\r\nentityName = context.parameters.entityName.raw ?\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 context.parameters.entityName.raw : context.parameters.fieldName.raw;\r\n\r\n\/\/Reading the parameters\r\n\r\ndropDownProps = {\r\n\r\nisDisable: isDisable,\r\n\r\nisMultiple: isMultiple,\r\n\r\nentityName: entityName,\r\n\r\ncontext: context,\r\n\r\nnotifyChange: this.notifyOnSelect.bind(this)\r\n\r\n}\r\n\r\nreturn React.createElement(\r\n\r\nDynamicDropdown, dropDownProps\r\n\r\n);\r\n\r\n}<\/pre>\n<p>We will create a <strong>Helper.ts<\/strong> file containing the functions and then create the object of the class containing all the functions in <strong>App.tsx<\/strong> file which consists of a functional component. We have also passed a dependency to ensure that the useEffect() gets called every time there\u2019s a change in the entity name.<\/p>\n<p><strong>Helper.ts<\/strong><\/p>\n<pre class=\"lang:css gutter:true start:1\">public GetEntityAttribute = async (entityName: any) =&gt; {\r\n\r\n\/\/Local variables\r\n\r\nlet functionName: string = \"GetEntityAttribute()=&gt;\";\r\n\r\nlet res: any;\r\n\r\nlet attributesLogicalname: any = [];\r\n\r\nlet result: any;\r\n\r\nlet entityAttributes: any = [];\r\n\r\ntry {\r\n\r\nif (!this.isValid(entityName)) {\r\n\r\nreturn { options: entityAttributes }\r\n\r\n}\r\n\r\n\/\/Making request for entity metadata to get logical names of the attributes\r\n\r\nres = await this._context.utils.getEntityMetadata(entityName);\r\n\r\n\/\/Getting all logical name of the attributes and storing it in the array\r\n\r\nattributesLogicalname = res._entityDescriptor.AttributeNames;\r\n\r\n\/\/Making request to get logical name as well as display name of the attributes\r\n\r\nresult = await this._context.utils.getEntityMetadata(entityName,\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 attributesLogicalname);\r\n\r\n\/\/Converting the object keys to an array for iteration\r\n\r\nlet response = Object.keys(result.Attributes._collection);\r\n\r\n\/\/Pushing the attributes into the array\r\n\r\nfor (let j = 0; j &lt; response.length; j++) {\r\n\r\nif (result.Attributes._collection[response[j]].DisplayName != null) {\r\n\r\nentityAttributes.push({\r\n\r\nkey: result.Attributes._collection[response[j]].LogicalName,\r\n\r\ntext: result.Attributes._collection[response[j]].DisplayName\r\n\r\n})\r\n\r\n}\r\n\r\n}\r\n\r\nentityAttributes.sort(function (a: any, b: any) {\r\n\r\nif (a.text &lt; b.text) { return -1 }\r\n\r\nif (a.text &gt; b.text) { return 1 }\r\n\r\nreturn 0;\r\n\r\n});\r\n\r\n}\r\n\r\ncatch (error: any) {\r\n\r\n\/\/Handling error\r\n\r\nthis._context.navigation.openErrorDialog({ message: functionName + \": Kindly check the entity name and it must be in lowercase\" })\r\n\r\n}\r\n\r\nreturn { options: entityAttributes }\r\n\r\n}\r\n\u00a0\r\n\r\n<strong>App.tsx:<\/strong>\r\n\u00a0\r\n\r\nuseEffect(() =&gt; {\r\n\r\n_CrmHelper.GetEntityAttribute(props.entityName).then((success) =&gt; {\r\n\r\n\/\/Setting the dropdown options\r\n\r\nsetDropDownOptions(success.options)\r\n\r\n});\r\n\r\n}, [props.entityName])<\/pre>\n<p><strong>Field Interface Now:<\/strong><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-33311\" style=\"border: 1px solid #0a0a0a; padding: 1px; margin: 1px;\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/2virtual-PCF-control.jpeg\" alt=\"virtual PCF control\" width=\"973\" height=\"84\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/2virtual-PCF-control.jpeg 973w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/2virtual-PCF-control-300x26.jpeg 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/2virtual-PCF-control-768x66.jpeg 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/2virtual-PCF-control-660x57.jpeg 660w\" sizes=\"(max-width: 973px) 100vw, 973px\" \/><\/p>\n<h2><strong>Conclusion<\/strong><\/h2>\n<p>Thus, we saw how to use Async-await on a load of virtual PCF control.<\/p>\n<p><a href=\"https:\/\/www.inogic.com\/product\/productivity-apps\/auto-manage-lead-assignment-and-distribution-automation-dynamics-365-crm\" target=\"_blank\" rel=\"noopener\"><strong> <img decoding=\"async\" class=\"wp-image-33314 alignright\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/Lead-Assignment.png\" alt=\"\" width=\"820\" height=\"205\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/Lead-Assignment.png 800w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/Lead-Assignment-300x75.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/Lead-Assignment-768x192.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2022\/12\/Lead-Assignment-660x165.png 660w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/strong><\/a><\/p>\n<p><strong>\u00a0<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently while working on the virtual PCF control we noticed that the updateView() in the virtual PCF works in a different manner as compared to standard PCF control with async functions. In standard PCF control, the return type of the updateView() is void while in the virtual PCF the return type is react-element. So when\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.inogic.com\/blog\/2022\/12\/use-of-async-await-in-virtual-pcf-control\/\">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":[1913,44,1929,2053,2361],"tags":[1941],"class_list":["post-33310","post","type-post","status-publish","format-standard","hentry","category-microsoft-power-platform-services","category-power-apps","category-pcf","category-power-apps-portals","category-technical","tag-pcf-control"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/33310","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=33310"}],"version-history":[{"count":0,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/33310\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/media?parent=33310"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/categories?post=33310"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/tags?post=33310"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}