🛎️

【Flutter/web】dartからJavaScriptを使う

2024/12/04に公開

Flutter(web) で dart から JavaScript を呼べます

  1. web/index.htmlにJavaScriptを記述する
  2. js.context.callMethodでリクエスト

index.htmlにJavaScriptを記述

  • bodyタグの中に以下2種類のサンプルコードを記述します
  • sampleFunction は "data from javascript"というStringを返すだけです
  • incrementInt は intに+1して返すだけです
  <body>
    <script type="text/javascript">
      function sampleFunction(callback) {
        var data = "data from javascript";
        callback(data);
      }
    </script>

    <script type="text/javascript">
      /**
       * Increment an integer and call a callback with the result.
       * @param {number} value - The integer to increment.
       * @param {function(number): void} callback - The callback function.
       */
      function incrementInt(value, callback) {
        var data = value + 1;
        callback(data);
      }
    </script>
  </body>

dartからJavascriptを呼び出す

  • それぞれのJavaScriptを呼び出すElevatedButtonを配置
  • import 'dart:js' as js; でweb専用のjavascriptライブラリをimport
  • js.context.callMethod で任意の関数を呼び出し
  • incrementJavaScript でJSの足し算のをdart側に反映・更新
import 'dart:async';
import 'package:flutter/material.dart';
import 'dart:js' as js;

class JsCallbackPage extends StatefulWidget {
  const JsCallbackPage({Key? key}) : super(key: key);

  
  _JsCallbackPageState createState() => _JsCallbackPageState();
}

class _JsCallbackPageState extends State<JsCallbackPage> {
  Future<dynamic> requestJavaScript() async {
    Completer completer = Completer();
    js.context.callMethod(
      'sampleFunction',
      [
        js.allowInterop((response) {
          completer.complete(response);
        }),
      ],
    );
    Future<dynamic> future = completer.future;
    return future;
  }

  int count = 0;
  Future<dynamic> incrementJavaScript() async {
    Completer completer = Completer();
    js.context.callMethod(
      'incrementInt',
      [
        count,
        js.allowInterop((response) {
          completer.complete(response);
        }),
      ],
    );
    Future<dynamic> future = completer.future;

    return future;
  }

  
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(), body: body());
  }

  Widget body() {
    return Center(
      child: Column(
        children: [
          ElevatedButton(
            onPressed: () async {
              String response = await requestJavaScript();
              print(response);
            },
            child: const Text("Request Data from JavaScript"),
          ),
          Text("count: $count"),
          ElevatedButton(
            onPressed: () async {
              int response = await incrementJavaScript();
              print(response);
              setState(() {
                count = response;
              });
            },
            child: const Text("Request increment count from JavaScript"),
          ),
        ],
      ),
    );
  }
}

まとめ

JavaScriptで公開されているものを利用できると便利!
文字認識のTesseractのpubを見ると、web向けはjsを呼び出しています。

https://pub.dev/packages/flutter_tesseract_ocr

呼び出し部分はライブラリ側で吸収しているので、使いたいTesseractのバージョンを変えたい時や、渡す引数の形式を変えたい時などは、この例を参考に自分で呼び出し部分を実装すると良いです!

Discussion