For a Webview relate feature I had used Method channels to open Webview through Native Android & iOS code and I am opening a website in it, I was getting callback from JS to native code in mobile platforms. For Android I was providing a class whose method is getting called from JS, It looks something like this:
webView.settings.javaScriptEnabled = true
webView.addJavascriptInterface(WebAppInterface(this), "nativeCommunicator")
webView.loadUrl("SOME_URL")
…
class WebAppInterface(private val mContext: Activity) {
@JavascriptInterface
fun postMessage(text: String) {
println("WebAppInterface.message($text)")
//send back to flutter
}
}
Which seems quite straightforward way to get callback from js to my code.
Now I am trying to do this in Flutter Web I opened the website by calling
import 'package:js/js.dart';
...
js.context.callMethod('open', 'SOME_URL', '_self');
Which works fine, Now I am trying to get callback by creating this class
@JS()
library native_communicator;
import 'package:js/js.dart';
@JS('nativeCommunicator')
class NativeCommunicator{
@JS('postMessage')
external static set _postMessage(void Function(String text) f);
@JS()
external static void postMessage();
}
void setJSCallbackFunction(void Function(String text) postMessageFunction) {
NativeCommunicator._postMessage = allowInterop(postMessageFunction);
}
I am calling setJSCallbackFunction and passing my function as param, but it keeps giving me runtime error that It can not find 'postMessage', I tried some other way which leads to can not find 'nativeCommunicator' error, Can anyone point out how to do this right? I need to call a dart method from js.
I think you're looking for allowInterop
function from dart:js
library: https://api.flutter.dev/flutter/dart-js/dart-js-library.html
Sample code:
import 'dart:html';
import 'dart:js';
import 'package:js/js_util.dart';
String dartFunc(String str) {
return 'Inside dartFunc: ' + str;
}
void main() {
setProperty(window, 'dartFunc', allowInterop(dartFunc));
runApp(MyApp());
}
If you pass a Dart function to a JavaScript API as an argument, wrap the Dart function using allowInterop()
or allowInteropCaptureThis()
.
To make a Dart function callable from JavaScript by name, use a setter annotated with @JS()
.
Sample:
@JS()
library callable_function;
import 'package:js/js.dart';
/// Allows assigning a function to be callable from `window.functionName()`
@JS('functionName')
external set _functionName(void Function() f);
void _someDartFunction() {
print('Hello from Dart!');
}
void main() {
_functionName = allowInterop(_someDartFunction);
// JavaScript code may now call `functionName()` or `window.functionName()`.
}
From package:js
docs
@JS()
library native_communicator;
import 'package:js/js.dart';
@JS('nativeCommunicator')
class NativeCommunicator{
@JS('postMessage')
external static set _postMessage(void Function(String text) f);
// No need to do this as 'allowInterop()' will do the necessary.
//
// @JS()
// external static void postMessage();
//
// }
void setJSCallbackFunction(void Function(String text) postMessageFunction) {
NativeCommunicator._postMessage = allowInterop(postMessageFunction);
}
import 'path/to/setJSCallbackFunction-file';
void main() {
setJSCallbackFunction(param);
}
build/web/main.dart.js
postMessage
) allowInterop()
in main()
dart.main.js
is in scope.<script src"path/to/dart.main.js">
window.functionName(); // or functionName()
</script>
Prefer to define the js function as a top-level function which can be called with
window.functionName()
orfunctionName()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.