🔍

FileUploadInputElementが見つからない!

に公開

問題:FileUploadInputElementが見つからない!

chatGPTと戯れている時にこんなコードを教えてもらいました。

import 'dart:html' as html;

// 省略

final inputElement = html.FileUploadInputElement()..accept = 'image/*';

しかし、dart:htmlは、Deprecatedで使わない方が良さそうなので、移行ガイドに従って移行しようとしました。
ふむふむ、webパッケージをインポートすればよいと。

import 'package:web/web.dart' as web;

// 省略

final inputElement = web.FileUploadInputElement()..accept = 'image/*';

結果:The function 'FileUploadInputElement' isn't defined.
え!?見つからない!

webパッケージのAPIドキュメントで似たものを検索しても見つかりません。

解決策

これでdart:htmlを使っていた時と同等のことができます。

import 'package:web/web.dart' as web;

// 省略

final inputElement = web.document.createElement('input') as web.HTMLInputElement
  ..type = 'file'
  ..accept = 'image/*';

見つけ方

FileUploadInputElementの実装を見るとこのように書かれています。
中身はInputElementなんですね。

factory FileUploadInputElement() => new InputElement(type: 'file');

さらにInputElementのコンストラクタはこう実装されています。

factory InputElement({String? type}) {
  InputElement e = document.createElement("input") as InputElement;
  if (type != null) {
    try {
      // IE throws an exception for unknown types.
      e.type = type;
    } catch (_) {}
  }
  return e;
}

これらを合わせると、こうなるでしょう。

InputElement inputElement = document.createElement("input") as InputElement;
try {
  // IE throws an exception for unknown types.
  e.type = 'file';
} catch (_) {}

typeは固定なので、try-catchは不要です。
また、InputElementwebパッケージでは、Deprecatedです。推奨されているHTMLInputElementに書き換えると、解決策のコードになります。

さいごに

解決策を見つけるまで、名前が少し変わったのかであったり、実装が漏れているのかであったり、中々調査に時間を費やしました。
同じようなことになった人の助けになるといいなーと思います。

補足

image_picker_webでは同じことをするために、少し違う実装をしていたので、参考として記載します。

final input = web.HTMLInputElement()
  ..accept = '$type/*'
  ..type = 'file';

image_picker_web/lib/image_picker_web.dartのl.54-56より

Discussion