1# Invoking Application Functions on the Frontend Page 2 3Register your application code with frontend pages. Then you can invoke application methods with the registered object names on frontend pages. 4 5## Establishing an Interaction Channel Between the Application Side and the HTML5 Page 6 7Two methods are available for registering the application code:<br>Call [javaScriptProxy()](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#javascriptproxy) during **Web** component initialization. Call [registerJavaScriptProxy()](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#registerjavascriptproxy) after **Web** component initialization. The two methods must be used together with the [deleteJavaScriptRegister](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#deletejavascriptregister) API to prevent memory leaks. 8 9The following example registers the **test()** function with the frontend page. This way, the **test()** function can be triggered and run on the frontend page. 10 11 12- Sample code for using [javaScriptProxy()](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#javascriptproxy): 13 14 ```ts 15 // xxx.ets 16 import { webview } from '@kit.ArkWeb'; 17 import { BusinessError } from '@kit.BasicServicesKit'; 18 19 class TestClass { 20 constructor() { 21 } 22 23 test(): string { 24 return 'ArkTS Hello World!'; 25 } 26 } 27 28 @Entry 29 @Component 30 struct WebComponent { 31 webviewController: webview.WebviewController = new webview.WebviewController(); 32 // Declare the object to be registered. 33 @State testObj: TestClass = new TestClass(); 34 35 build() { 36 Column() { 37 Button('deleteJavaScriptRegister') 38 .onClick(() => { 39 try { 40 this.webviewController.deleteJavaScriptRegister("testObjName"); 41 } catch (error) { 42 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 43 } 44 }) 45 // Load the local index.html page. 46 Web({ src: $rawfile('index.html'), controller: this.webviewController}) 47 // Inject the object to the web client. 48 .javaScriptProxy({ 49 object: this.testObj, 50 name: "testObjName", 51 methodList: ["test"], 52 controller: this.webviewController, 53 // Optional parameter. 54 asyncMethodList: [], 55 permission: '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' + 56 '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' + 57 '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' + 58 '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' + 59 '{"scheme":"u","host":"v","port":"","path":""}]}]}}' 60 }) 61 } 62 } 63 } 64 ``` 65- Sample code for the application using [registerJavaScriptProxy()](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#registerjavascriptproxy) for registration: 66 67 ```ts 68 // xxx.ets 69 import { webview } from '@kit.ArkWeb'; 70 import { BusinessError } from '@kit.BasicServicesKit'; 71 72 class TestClass { 73 constructor() { 74 } 75 76 test(): string { 77 return "ArkUI Web Component"; 78 } 79 80 toString(): void { 81 console.log('Web Component toString'); 82 } 83 } 84 85 @Entry 86 @Component 87 struct Index { 88 webviewController: webview.WebviewController = new webview.WebviewController(); 89 @State testObj: TestClass = new TestClass(); 90 91 build() { 92 Column() { 93 Button('refresh') 94 .onClick(() => { 95 try { 96 this.webviewController.refresh(); 97 } catch (error) { 98 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 99 } 100 }) 101 Button('Register JavaScript To Window') 102 .onClick(() => { 103 try { 104 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"], 105 // Optional parameter: asyncMethodList 106 [], 107 // Optional parameter: permission 108 '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' + 109 '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' + 110 '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' + 111 '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' + 112 '{"scheme":"u","host":"v","port":"","path":""}]}]}}' 113 ); 114 } catch (error) { 115 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 116 } 117 }) 118 Button('deleteJavaScriptRegister') 119 .onClick(() => { 120 try { 121 this.webviewController.deleteJavaScriptRegister("testObjName"); 122 } catch (error) { 123 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 124 } 125 }) 126 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 127 } 128 } 129 } 130 ``` 131 132 > **NOTE** 133 > 134 > - You need to call the [refresh()](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#refresh) method for the registration to take effect after using the [registerJavaScriptProxy()](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#registerjavascriptproxy) method. 135 136- The optional parameter permission is a JSON string. The following is an example: 137 ```json 138 { 139 "javascriptProxyPermission": { 140 "urlPermissionList": [ // Object-level permission. If it is granted, all methods are available. 141 { 142 "scheme": "resource", // Exact match. This field is mandatory and cannot be empty. 143 "host": "rawfile", // Exact match. This field is mandatory and cannot be empty. 144 "port": "", // Exact match. If the value is empty, the check is not performed. This field is mandatory. 145 "path": "" // Prefix match. If the value is empty, the check is not performed. This field is mandatory. 146 }, 147 { 148 "scheme": "https", // Exact match. This field is mandatory and cannot be empty. 149 "host": "xxx.com", // Exact match. This field is mandatory and cannot be empty. 150 "port": "8080", // Exact match. If the value is empty, the check is not performed. This field is mandatory. 151 "path": "a/b/c" // Prefix match. If the value is empty, the check is not performed. This parameter is mandatory. 152 } 153 ], 154 "methodList": [ 155 { 156 "methodName": "test", 157 "urlPermissionList": [ // Method-level permission. 158 { 159 "scheme": "https", // Exact match. This field is mandatory and cannot be empty. 160 "host": "xxx.com", // Exact match. This field is mandatory and cannot be empty. 161 "port": "", // Exact match. If the value is empty, the check is not performed. This field is mandatory. 162 "path": "" // Prefix match. If the value is empty, the check is not performed. This parameter is mandatory. 163 }, 164 { 165 "scheme": "resource",// Exact match. This field is mandatory and cannot be empty. 166 "host": "rawfile", // Exact match. This field is mandatory and cannot be empty. 167 "port": "", // Exact match. If the value is empty, the check is not performed. This field is mandatory. 168 "path": "" // Prefix match. If the value is empty, the check is not performed. This field is mandatory. 169 } 170 ] 171 }, 172 { 173 "methodName": "test11", 174 "urlPermissionList": [ // Method-level permission. 175 { 176 "scheme": "q", // Exact match. This field is mandatory and cannot be empty. 177 "host": "r", // Exact match. This field is mandatory and cannot be empty. 178 "port": "", // Exact match. If the value is empty, the check is not performed. This field is mandatory. 179 "path": "t" // Prefix match. If the value is empty, the check is not performed. This field is mandatory. 180 }, 181 { 182 "scheme": "u", // Exact match. This field is mandatory and cannot be empty. 183 "host": "v", // Exact match. This field is mandatory and cannot be empty. 184 "port": "", // Exact match. If the value is empty, the check is not performed. This field is mandatory. 185 "path": "" // Prefix match. If the value is empty, the check is not performed. This field is mandatory. 186 } 187 ] 188 } 189 ] 190 } 191 } 192 ``` 193 194- Sample code for invoking application functions on the **index.html** frontend page: 195 196 ```html 197 <!-- index.html --> 198 <!DOCTYPE html> 199 <html> 200 <body> 201 <button type="button" onclick="callArkTS()">Click Me!</button> 202 <p id="demo"></p> 203 <script> 204 function callArkTS() { 205 let str = testObjName.test(); 206 document.getElementById("demo").innerHTML = str; 207 console.info('ArkTS Hello World! :' + str); 208 } 209 </script> 210 </body> 211 </html> 212 ``` 213## Usage of Complex Types 214 215### Passing Arrays Between the Application and the Frontend Page 216 217 Arrays can be used as parameters or return values of object registration methods and passed between applications and frontend pages. 218 ```ts 219 // xxx.ets 220 import { webview } from '@kit.ArkWeb'; 221 import { BusinessError } from '@kit.BasicServicesKit'; 222 223 class TestClass { 224 constructor() { 225 } 226 227 test(): Array<Number> { 228 return [1, 2, 3, 4] 229 } 230 231 toString(param: String): void { 232 console.log('Web Component toString' + param); 233 } 234 } 235 236 @Entry 237 @Component 238 struct Index { 239 webviewController: webview.WebviewController = new webview.WebviewController(); 240 @State testObj: TestClass = new TestClass(); 241 242 build() { 243 Column() { 244 Button('refresh') 245 .onClick(() => { 246 try { 247 this.webviewController.refresh(); 248 } catch (error) { 249 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 250 } 251 }) 252 Button('Register JavaScript To Window') 253 .onClick(() => { 254 try { 255 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 256 } catch (error) { 257 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 258 } 259 }) 260 Button('deleteJavaScriptRegister') 261 .onClick(() => { 262 try { 263 this.webviewController.deleteJavaScriptRegister("testObjName"); 264 } catch (error) { 265 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 266 } 267 }) 268 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 269 } 270 } 271 } 272 ``` 273 274 ```html 275 <!-- index.html --> 276 <!DOCTYPE html> 277 <html> 278 <body> 279 <button type="button" onclick="callArkTS()">Click Me!</button> 280 <p id="demo"></p> 281 <script> 282 function callArkTS() { 283 testObjName.toString(testObjName.test()); 284 } 285 </script> 286 </body> 287 </html> 288 ``` 289 290### Using Complex Types Excluding Functions 291 292 Sample code for passing complex types (excluding functions) as parameters or return values in object registration methods between the application and the frontend page: 293 ```ts 294 // xxx.ets 295 import { webview } from '@kit.ArkWeb'; 296 import { BusinessError } from '@kit.BasicServicesKit'; 297 298 class Student { 299 name: string = ''; 300 age: string = ''; 301 } 302 303 class TestClass { 304 constructor() { 305 } 306 307 // Data of primitive types to pass: name:"jeck", age:"12" 308 test(): Student { 309 let st: Student = { name: "jeck", age: "12" }; 310 return st; 311 } 312 313 toString(param: ESObject): void { 314 console.log('Web Component toString' + param["name"]); 315 } 316 } 317 318 @Entry 319 @Component 320 struct Index { 321 webviewController: webview.WebviewController = new webview.WebviewController(); 322 @State testObj: TestClass = new TestClass(); 323 324 build() { 325 Column() { 326 Button('refresh') 327 .onClick(() => { 328 try { 329 this.webviewController.refresh(); 330 } catch (error) { 331 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 332 } 333 }) 334 Button('Register JavaScript To Window') 335 .onClick(() => { 336 try { 337 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 338 } catch (error) { 339 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 340 } 341 }) 342 Button('deleteJavaScriptRegister') 343 .onClick(() => { 344 try { 345 this.webviewController.deleteJavaScriptRegister("testObjName"); 346 } catch (error) { 347 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 348 } 349 }) 350 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 351 } 352 } 353 } 354 ``` 355 356 ```html 357 <!-- index.html --> 358 <!DOCTYPE html> 359 <html> 360 <body> 361 <button type="button" onclick="callArkTS()">Click Me!</button> 362 <p id="demo"></p> 363 <script> 364 function callArkTS() { 365 testObjName.toString(testObjName.test()); 366 } 367 </script> 368 </body> 369 </html> 370 ``` 371### Invoking a Callback of the Frontend Page from the Application 372 373 Callbacks can be used as parameters or return values of object registration methods and passed between applications and frontend pages. 374 ```ts 375 // xxx.ets 376 import { webview } from '@kit.ArkWeb'; 377 import { BusinessError } from '@kit.BasicServicesKit'; 378 379 class TestClass { 380 constructor() { 381 } 382 383 test(param: Function): void { 384 param("call callback"); 385 } 386 387 toString(param: String): void { 388 console.log('Web Component toString' + param); 389 } 390 } 391 392 @Entry 393 @Component 394 struct Index { 395 webviewController: webview.WebviewController = new webview.WebviewController(); 396 @State testObj: TestClass = new TestClass(); 397 398 build() { 399 Column() { 400 Button('refresh') 401 .onClick(() => { 402 try { 403 this.webviewController.refresh(); 404 } catch (error) { 405 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 406 } 407 }) 408 Button('Register JavaScript To Window') 409 .onClick(() => { 410 try { 411 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 412 } catch (error) { 413 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 414 } 415 }) 416 Button('deleteJavaScriptRegister') 417 .onClick(() => { 418 try { 419 this.webviewController.deleteJavaScriptRegister("testObjName"); 420 } catch (error) { 421 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 422 } 423 }) 424 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 425 } 426 } 427 } 428 ``` 429 430 ```html 431 <!-- index.html --> 432 <!DOCTYPE html> 433 <html> 434 <body> 435 <button type="button" onclick="callArkTS()">Click Me!</button> 436 <p id="demo"></p> 437 <script> 438 function callArkTS() { 439 testObjName.test(function(param){testObjName.toString(param)}); 440 } 441 </script> 442 </body> 443 </html> 444 ``` 445### Calling the Function in an Object of the Frontend Page from the Application Side 446 447 The function in an object of the frontend page can be used as the parameter or return value of the registration object method and passed between the application side and the frontend page. 448 ```ts 449 // xxx.ets 450 import { webview } from '@kit.ArkWeb'; 451 import { BusinessError } from '@kit.BasicServicesKit'; 452 453 class TestClass { 454 constructor() { 455 } 456 457 test(param: ESObject): void { 458 param.hello("call obj func"); 459 } 460 461 toString(param: String): void { 462 console.log('Web Component toString' + param); 463 } 464 } 465 466 @Entry 467 @Component 468 struct Index { 469 webviewController: webview.WebviewController = new webview.WebviewController(); 470 @State testObj: TestClass = new TestClass(); 471 472 build() { 473 Column() { 474 Button('refresh') 475 .onClick(() => { 476 try { 477 this.webviewController.refresh(); 478 } catch (error) { 479 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 480 } 481 }) 482 Button('Register JavaScript To Window') 483 .onClick(() => { 484 try { 485 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 486 } catch (error) { 487 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 488 } 489 }) 490 Button('deleteJavaScriptRegister') 491 .onClick(() => { 492 try { 493 this.webviewController.deleteJavaScriptRegister("testObjName"); 494 } catch (error) { 495 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 496 } 497 }) 498 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 499 } 500 } 501 } 502 ``` 503 504 ```html 505 <!-- index.html --> 506 <!DOCTYPE html> 507 <html> 508 <body> 509 <button type="button" onclick="callArkTS()">Click Me!</button> 510 <p id="demo"></p> 511 <script> 512 // Method 1 513 class Student { 514 constructor(nameList) { 515 this.methodNameListForJsProxy = nameList; 516 } 517 518 hello(param) { 519 testObjName.toString(param) 520 } 521 } 522 var st = new Student(["hello"]) 523 524 // Method 2 525 // Create a constructor, with the first letter of the constructor capitalized. 526 function Obj1(){ 527 this.methodNameListForJsProxy=["hello"]; 528 this.hello=function(param){ 529 testObjName.toString(param) 530 }; 531 } 532 // Use the constructor to create an object using the new keyword. 533 var st1 = new Obj1(); 534 535 function callArkTS() { 536 testObjName.test(st); 537 testObjName.test(st1); 538 } 539 </script> 540 </body> 541 </html> 542 ``` 543 544### Calling the Function in an Object of the Application Side from the Frontend Page 545 546 The function in an object of the application side can be used as the parameter or return value of the registration object method and passed between the application side and the frontend page. 547 ```ts 548 // xxx.ets 549 import { webview } from '@kit.ArkWeb'; 550 import { BusinessError } from '@kit.BasicServicesKit'; 551 552 class ObjOther { 553 methodNameListForJsProxy: string[] 554 555 constructor(list: string[]) { 556 this.methodNameListForJsProxy = list 557 } 558 559 testOther(json: string): void { 560 console.info(json) 561 } 562 } 563 564 class TestClass { 565 ObjReturn: ObjOther 566 567 constructor() { 568 this.ObjReturn = new ObjOther(["testOther"]); 569 } 570 571 test(): ESObject { 572 return this.ObjReturn 573 } 574 575 toString(param: string): void { 576 console.log('Web Component toString' + param); 577 } 578 } 579 580 @Entry 581 @Component 582 struct Index { 583 webviewController: webview.WebviewController = new webview.WebviewController(); 584 @State testObj: TestClass = new TestClass(); 585 586 build() { 587 Column() { 588 Button('refresh') 589 .onClick(() => { 590 try { 591 this.webviewController.refresh(); 592 } catch (error) { 593 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 594 } 595 }) 596 Button('Register JavaScript To Window') 597 .onClick(() => { 598 try { 599 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 600 } catch (error) { 601 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 602 } 603 }) 604 Button('deleteJavaScriptRegister') 605 .onClick(() => { 606 try { 607 this.webviewController.deleteJavaScriptRegister("testObjName"); 608 } catch (error) { 609 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 610 } 611 }) 612 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 613 } 614 } 615 } 616 ``` 617 618 ```html 619 <!-- index.html --> 620 <!DOCTYPE html> 621 <html> 622 <body> 623 <button type="button" onclick="callArkTS()">Click Me!</button> 624 <p id="demo"></p> 625 <script> 626 function callArkTS() { 627 testObjName.test().testOther("call other object func"); 628 } 629 </script> 630 </body> 631 </html> 632 ``` 633 634### Using Promises 635 636 Create a promise on the application side. Use the promise as the parameter or return value of the object method and pass it to the frontend page. 637 ```ts 638 // xxx.ets 639 import { webview } from '@kit.ArkWeb'; 640 import { BusinessError } from '@kit.BasicServicesKit'; 641 642 class TestClass { 643 constructor() { 644 } 645 646 test(): Promise<string> { 647 let p: Promise<string> = new Promise((resolve, reject) => { 648 setTimeout(() => { 649 console.log ('Execution completed'); 650 reject('fail'); 651 }, 10000); 652 }); 653 return p; 654 } 655 656 toString(param: String): void { 657 console.log(" " + param); 658 } 659 } 660 661 @Entry 662 @Component 663 struct Index { 664 webviewController: webview.WebviewController = new webview.WebviewController(); 665 @State testObj: TestClass = new TestClass(); 666 667 build() { 668 Column() { 669 Button('refresh') 670 .onClick(() => { 671 try { 672 this.webviewController.refresh(); 673 } catch (error) { 674 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 675 } 676 }) 677 Button('Register JavaScript To Window') 678 .onClick(() => { 679 try { 680 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 681 } catch (error) { 682 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 683 } 684 }) 685 Button('deleteJavaScriptRegister') 686 .onClick(() => { 687 try { 688 this.webviewController.deleteJavaScriptRegister("testObjName"); 689 } catch (error) { 690 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 691 } 692 }) 693 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 694 } 695 } 696 } 697 ``` 698 699 ```html 700 <!-- index.html --> 701 <!DOCTYPE html> 702 <html> 703 <body> 704 <button type="button" onclick="callArkTS()">Click Me!</button> 705 <p id="demo"></p> 706 <script> 707 function callArkTS() { 708 testObjName.test().then((param)=>{testObjName.toString(param)}).catch((param)=>{testObjName.toString(param)}) 709 } 710 </script> 711 </body> 712 </html> 713 ``` 714 Create a promise on the frontend page. Use the promise as the parameter or return value of the object method and pass it to the application side. 715 ```ts 716 // xxx.ets 717 import { webview } from '@kit.ArkWeb'; 718 import { BusinessError } from '@kit.BasicServicesKit'; 719 720 class TestClass { 721 constructor() { 722 } 723 724 test(param:Function): void { 725 setTimeout( () => { param("suc") }, 10000) 726 } 727 728 toString(param:String): void { 729 console.log(" " + param); 730 } 731 } 732 733 @Entry 734 @Component 735 struct Index { 736 webviewController: webview.WebviewController = new webview.WebviewController(); 737 @State testObj: TestClass = new TestClass(); 738 739 build() { 740 Column() { 741 Button('refresh') 742 .onClick(() => { 743 try { 744 this.webviewController.refresh(); 745 } catch (error) { 746 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 747 } 748 }) 749 Button('Register JavaScript To Window') 750 .onClick(() => { 751 try { 752 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 753 } catch (error) { 754 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 755 } 756 }) 757 Button('deleteJavaScriptRegister') 758 .onClick(() => { 759 try { 760 this.webviewController.deleteJavaScriptRegister("testObjName"); 761 } catch (error) { 762 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 763 } 764 }) 765 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 766 } 767 } 768 } 769 ``` 770 771 ```html 772 <!-- index.html --> 773 <!DOCTYPE html> 774 <html> 775 <body> 776 <button type="button" onclick="callArkTS()">Click Me!</button> 777 <p id="demo"></p> 778 <script> 779 function callArkTS() { 780 let funpromise 781 var p = new Promise(function(resolve, reject){funpromise=(param)=>{resolve(param)}}) 782 testObjName.test(funpromise) 783 p.then((param)=>{testObjName.toString(param)}) 784 } 785 </script> 786 </body> 787 </html> 788 ``` 789## Checking Whether the Channel Is Successfully Established 790 7911. Enable web debugging. 792 793 For details about how to enable web debugging, see [Debugging Frontend Pages by Using DevTools](web-debugging-with-devtools.md). 794 7952. Use an example to check whether the channel is successfully established. 796 797 The following example passes arrays between the application side and the frontend page described in [Usage of Complex Types](#usage-of-complex-types). The debugging result is shown in the following figure. 798 799  800