tyoshikawa1106のブログ

- Force.com Developer Blog -

SFDC:【改良版】RemoteActionと複数ファイルのアップロードについて

少し前にRemoteActionをつかってファイルアップロードする方法についてブログにまとめました。


これを書いた後ですが、テストのときに大きめのファイルをアップロードしたところ、とあるエラーが発生してしまいました。『Input too long. 』というエラーです。
f:id:tyoshikawa1106:20160209011013p:plain


このInput too longエラーの原因ですが、大きいファイルを1回でアップロードしようとすることで発生するみたいです。1つのファイルを分割して登録していくという対応が必要になるとのことです。


これについての詳細はこちらのブログで詳しく解説されていました。
f:id:tyoshikawa1106:20160209011705p:plain

Uploading Attachments to Salesforce using Javascript Remoting | ForceAdventure


上記ブログで紹介されていた対応方法でInput too longエラーの問題は解決しました。


ですが、今回は1ファイルのアップロードだけでなく複数ファイルの一括アップロードもできるようにする必要がありました。そのためループ処理でRemoteActionをファイル件数分実行してみたのですが、次のエラーが発生しました。

Cannot read property 'tid' of undefined


検索してみるとRemoteAction処理が正常に呼び出せなかった時に発生するみたいでした。1ファイルのアップロードなら3MBのファイルでもアップロードできたのですが複数ファイルをアップロードしようとするとエラーになります。おそらく非同期処理のRemoteActionが並列実行されるとエラーになる感じではないかと思います。


RemoteActionが順番に実行されれば解決するかと思いAngularJsのPromiseなどで頑張ってみたのですが、この方法ではうまくいきませんでした。


そのときの試行錯誤のイメージがこちらです....

https://gist.github.com/tyoshikawa1106/eb8b3a5f0c9eb48894de


考えられる対応方法は一通り試してみたのですがうまくいく気配がなかったので、何か参考になる情報はないか探してみたところ、まさしくやりたいことについてまとめてくれているブログがありました。

f:id:tyoshikawa1106:20160209013149p:plain

Salesforce MVP Brings Multi-file Uploading to Salesforce


これをベースに試してみたところ、大きいファイルサイズの一括アップロード処理を動かすことができました。


実際にアップロード処理を行っているときのデモ動画です。


完成したサンプルコードはこちらになります。


結局Promiseをつかった非同期制御は必要なかったみたいです。試行錯誤していたときは複雑な感じの書き方になっていたのですが、実際に動いたコードはすごくスッキリしていました。


いくつかのパターンを確認してみて、1ファイルのアップロードも複数ファイルの一括アップロードも1MBを超える大きなファイルのアップロードも正常に実行できたので、RemoteActionのファイルアップロードはこの方法で対応できそうです。


このファイルアップロード処理は他の場面でも汎用的に利用出来そうな感じでした。


とりあえず、海外の開発者の方がブログにまとめていてくれて本当に助かりました。