AuraでもSalesforce Canvasが使いたい

# はじめに

https://qiita.com/takaHAL/items/d6fb65c8283beffbf878

https://qiita.com/takaHAL/items/6caa83a199adcb7783cc

https://qiita.com/takaHAL/items/9150fae5dce87c90ff3a

https://qiita.com/takaHAL/items/6fa0d76a4056045d76bc

これまで、Canvas系の記事を何個か上げてきましたが
Visualforceを中心としたものでした。
今回は、Auraを使って基本的な読み込みを試していこうと思います。

:::note 
検証につかう環境は、trailheadのハンズオン環境です。
出てくるデータも初期のデモデータになります。
:::


# なぜ、Auraで読み込みたいのか？

Visualforceでキャンバスアプリケーションを読み込むのに遅いと感じたから。

なぜ、遅いと感じたのか？

https://trailhead.salesforce.com/ja/content/learn/modules/lex_dev_lc_vf_concepts/lex_dev_lc_vf_concepts_basics

>![スクリーンショット 2022-12-15 3.02.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/a98a1547-a70a-751d-0526-e4cef134cb99.png)
https://trailhead.salesforce.com/ja/content/learn/modules/lex_dev_lc_vf_concepts/lex_dev_lc_vf_concepts_basics

Visualforceはサーバー側でレンダリングされてからクライアントにHTMLを届ける。その後キャンバスの読みこみが走るため遅いもしくは、遅いと感じやすい。
Auraはアプリケーションまたはコンポーンネントバンドルをクライアントに返し、そこからJavaScriptでUIの生成が始まるので
初期読み込み分ユーザ体験がよい。
速度に関しては、キャンバス以外の処理が増えれば増えるほど如実に現れると思う

LWCを使用したかったが、キャンバスアプリケーションに非対応なためAuraで実装する

# Visualforceから変更することによって大きく変わること

https://developer.salesforce.com/docs/component-library/bundle/force:canvasApp/documentation

## entityFieldsがない

https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_vf_component_ref.htm

Visualforceでは、キャンバスアプリケーションに表示しているオブジェクトページの項目の値を渡すことができる
`entityFields`というものがあったが、Auraにはない。
これは予想でしかないが、サーバー側でレンダリングされるVisualforceだからこそあったものなのではないだろうか？

```html
<apex:page>
  <apex:canvasApp developerName="canvasAppTest"
    height="1000px" width="100%"
    entityFields="Phone, Name" />
</apex:page>
```

## entityFieldsの代用

https://developer.salesforce.com/docs/atlas.ja-jp.208.0.lightning.meta/lightning/aura_compref_force_canvasApp.htm

Auraでは、Visualforceでも使用できたparametersを使ってキャンバスアプリケーションに値を渡すことになる。

```html:
<aura:component>
    <force:canvasApp developerName="MyCanvasApp"
      namespacePrefix="myNamespace"
      parameters="{param1:'value1',param2:'value2'}" />
</aura:component>
```

# 実装する

アプリケーションは別の記事で作成したものを使います。

https://qiita.com/takaHAL/items/6fa0d76a4056045d76bc#%E6%8E%A5%E7%B6%9A%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3



## Auraコンポーネントの作成

### parametersを渡してみる

```html: canvasAppTest
<aura:component
  implements="flexipage:availableForRecordHome"
  access="global"
>
  <force:canvasApp
    developerName="canvasAppTest"
    maxHeight="infinite"
    width="100%"
    parameters="{param1:'value1',param2:'value2'}"
  />
</aura:component>
```

コンポーネントを作成できましたので、検証してみましょう。
問題なく表示されました。見た目に関しても今のLightningページにあっていてかっこいいですね！

![株式会社-Salesforce-Canvas-Salesforce (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/a07770ff-b6b5-bc47-292d-7e3cd8673cbf.png)

パラメータも問題なく取得できました。

![スクリーンショット 2022-12-15 3.43.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/7f561734-547d-f733-a620-b66361fb0daf.png)

### レコード情報をparametersにつける

`parameters="{param1:'value1',param2:'value2'}"`このような静的なパラメータは問題なく利用できましたが、
キャンバスアプリケーションにレコードの情報を渡したいというケースがあるともいます。

表示した後、イベント送信で渡してもいいかもですが

今回は、キャンバスアプリケーションを表示時に渡してみます。

1\. 表示しているレコードページのIDを取得できるようにする

```diff_html: canvasAppTest
<aura:component
+  implements="flexipage:availableForRecordHome, force:hasRecordId"
   access="global"
>
+ <aura:attribute name="recordId" type="String" />
  <force:canvasApp
    developerName="canvasAppTest"
    maxHeight="infinite"
    width="100%"
    parameters="{param1:'value1',param2:'value2'}"
  />
</aura:component>
```

2\. `force:recordData`でレコードを読み込む

https://trailhead.salesforce.com/ja/content/learn/modules/lightning_data_service/lightning_data_service_manipulate_records

```diff_html: canvasAppTest
<aura:component
   implements="flexipage:availableForRecordHome, force:hasRecordId"
   access="global"
>
  <aura:attribute name="recordId" type="String" />
+ <aura:attribute name="record" type="Object" />
+ <aura:attribute name="account" type="Object" />
+ <aura:attribute name="recordError" type="String" />
+ <force:recordData aura:id="record"
+     fields="Name"
+     recordId="{!v.recordId}"
+     targetError="{!v.recordError}"
+     targetRecord="{!v.record}"
+     targetFields ="{!v.account}"
+     mode="VIEW"/>
+  取引先：{!v.account.Name}
  <force:canvasApp
    developerName="canvasAppTest"
    maxHeight="infinite"
    width="100%"
    parameters="{param1:'value1',param2:'value2'}"
  />
+ <aura:if isTrue="{!not(empty(v.recordError))}">
+   <div class="recordError">
+       {!v.recordError}
+   </div>
+ </aura:if>
</aura:component>
```

無事取引先名がAuraで取得できました。

![株式会社-Salesforce-Canvas-Salesforce (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/88065108-582c-1708-034a-eb115cbfb9ca.png)

3\. 取得したレコード情報をparametersに渡す

```diff_html
<aura:component
  implements="flexipage:availableForRecordHome,force:hasRecordId"
  access="global"
>
  <aura:attribute name="recordId" type="String" />
  <aura:attribute name="record" type="Object" />
  <aura:attribute name="account" type="Object" />
  <aura:attribute name="recordError" type="String" />
  <force:recordData aura:id="record"
      fields="Name"
      recordId="{!v.recordId}"
      targetError="{!v.recordError}"
      targetRecord="{!v.record}"
      targetFields ="{!v.account}"
      mode="VIEW"/>
  取引先：{!v.account.Name}

+ <aura:attribute name="jf" type="String" default='{"Name":"' />
+ <aura:attribute name="je" type="String" default='"}' />
  <force:canvasApp
    developerName="canvasAppTest"
    maxHeight="infinite"
    width="100%"
+   parameters="{!v.jf + v.account.Name + v.je}"
  />
  <aura:if isTrue="{!not(empty(v.recordError))}">
    <div class="recordError">
        {!v.recordError}
    </div>
  </aura:if>
</aura:component>

```

取得することができました！

![スクリーンショット 2022-12-15 4.22.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/96097a5a-9c7b-f820-3139-4707db8ae5b8.png)

## Visualforceと同時に開いてみる

用意したVisualforce

AuraでentityFieldsの代わりに、parametersで取引先名を渡しました。
Visualforceでは、entityFieldsをNameにして比較します。

```html
<apex:page>
  <apex:canvasApp developerName="canvasAppTest"
    maxHeight="infinite" width="100%" entityFields="Name" />
</apex:page>
```

どちらもレコード情報が渡せていますね

![スクリーンショット 2022-12-15 4.49.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/d7b6d5a1-e4f9-36a6-3bfd-2fa0b998045a.png)

![スクリーンショット 2022-12-15 4.49.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/98a23bb3-0999-d8de-a94b-cef27fed9a00.png)

表示はどうなるかというと`左がAura` `右がVisualforce`です。
左の方が若干早いのと、読み込み時の体験的にもAuraの方が優れていますね。

![株式会社_Salesforce_Canvas___Salesforce_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/7e826a0c-65eb-9437-895c-be535eba9b2a.gif)


# さいごに

今回は、Auraでキャンバスアプリケーションを読み込んでみました。
多少の差ですが速度も改善しそうです　速度もそうですが読み込み時の体験も含めて基本はAuraで実装をしようかなと思いました。
ただ、Visualforceの方が`entityFields`が便利なので初期表示系のキャンバスはAura、タブの中にあるようなキャンバスはVisualforceみたいに実装コストを加味してどっちを使うか決めてもいいかもですね。

Salesforceを長く使ってくれるのは社内の人なので、少しでも少しでも今後体験を良くしていきたいですね。

Aura自体は、ほとんど書いたことがないので何かアドバイスがあればコメントでいただけると助かります。

# 参考

https://qiita.com/takaHAL/items/d6fb65c8283beffbf878

https://qiita.com/takaHAL/items/6caa83a199adcb7783cc

https://qiita.com/takaHAL/items/9150fae5dce87c90ff3a

https://qiita.com/takaHAL/items/6fa0d76a4056045d76bc

https://developer.salesforce.com/docs/component-library/bundle/force:canvasApp/documentation

https://developer.salesforce.com/docs/atlas.ja-jp.platform_connect.meta/platform_connect/canvas_app_vf_component_ref.htm