Flutter Web ⇔ JavaScript — Everything that you need to know

Pratik Butani
7Span
Published in
4 min readJul 7, 2022
Flutter Web + JavaScript by Pratik Butani (7Span)

Common Questions from FlutterDev:

  • How do I pass the values from Flutter to JavaScript?
  • How to get a response from JavaScript to Flutter?
  • How can I wait for a response from JavaScript?
  • How can we open a new window of browser in Flutter Web?

At the end of the blog you will get all the answers related to Flutter Web with JavaScript.

Overview:

The web itself is a flexible platform, but Flutter is ideal for building web applications like PWAs or SPAs and bringing your existing mobile app to the web.

Benefits of Flutter Web (Source: flutter.dev/web)

Dart.js is a built-in library that can interop with JavaScript but as per documentation we should usually use package:js instead of this library.

For more information, see the JS interop page.

Let's see step by step:

Step 1: Add package:js into pubspec.yaml

dependencies:
js: ^0.6.4

Step 2: Create a JavaScript Library file

I have created a JavaScript library file at lib/js/js_library.dart

@JS()
library script.js;

import 'package:js/js.dart';

// This function will do Promise to return something
@JS()
external dynamic jsPromiseFunction(String message);

// This function will open new popup window for given URL.
@JS()
external dynamic jsOpenTabFunction(String url);
/// ^ ^ ^
/// return functionName arguments

Here I have created two functions.

The first one is jsPromiseFunction in which I will pass some string and it will return with a modified string by JS.

The second one is jsOpenTabFunction with URL which is passed in the argument and it will show an alert once that popup is closed.

We have imported script.js into an above file. We will write our logic into this JavaScript file that will be available in our web folder as below:

script.js location in our flutter project

Here is the code of script.js :

function getPlatform() {
return navigator.platform;
}

async function jsPromiseFunction(message) {
let msg = message;
let promise = new Promise(function(resolve, reject) {
resolve('Hello : ' + message);
});
let result = await promise;
return result;
}

async function jsOpenTabFunction(url) {
let promise = new Promise(function(resolve, reject) {
var win = window.open(url,"New Popup Window","width=800,height=800");
console.log("window",win);

var timer = setInterval(function() {
if (win.closed) {
clearInterval(timer);
alert("'Popup Window' closed!");
resolve('Paid');
}
}, 500);
console.log("window",win);
});
let result = await promise;
console.log("result",result);
return result;
}

Let's understand how that function will be called. So we will create one helper class that will decide whether the compilation platform is Mobile or Web so we can import the file based on that.

Let me show you the code of that file: (js_helper.dart)

// THIS FILE WILL PREVENT COMPILE TIME ERRORS,
// WHICH OCCURS BECAUSE OF PLATFORM DEPENDENT IMPORTS...

export 'js_helper_mobile.dart' // By default
if (dart.library.js) 'js_helper_web.dart'
if (dart.library.io) 'js_helper_mobile.dart';

/// The compiler will then say something like this:
/// Let’s export 'js_helper_mobile.dart' By default,
/// but if the "dart.library.js" is available, export 'js_helper_web.dart'.
/// But hey, if "dart.library.io" is available, export 'js_helper_mobile.dart'!

Note: This file will allow import based on platform (like dart.library.js is for web and dart.library.io is for mobile.

Now we will create both files for Mobile and Web. Let's have a look:

js_helper_web.dart:

import 'dart:js' as js;

import 'package:js/js_util.dart';

import 'js_library.dart';

class JSHelper {
/// This method name inside 'getPlatform' should be same in JavaScript file
String getPlatformFromJS() {
return js.context.callMethod('getPlatform');
}

Future<String> callJSPromise() async {
return await promiseToFuture(jsPromiseFunction("I am back from JS"));
}

Future<String> callOpenTab() async {
return await promiseToFuture(jsOpenTabFunction('https://google.com/'));
}
}

Note: Both the file will have the same class name and same method names. We will write the logic into a Web file only. The mobile file will have empty methods.

Here is the js_helper_mobile.dart:

class JSHelper {
String getPlatformFromJS() {
return "";
}

Future<String> callOpenTab() {
return Future.value('');
}

Future<String> callJSPromise() async {
return "";
}
}

Confused??? 😆

Don’t be confused. Let's have an example.

Let’s check how to use it.

Create an object of JSHelper class.

final JSHelper _jsHelper = JSHelper();

Calling the first method to get a platform:

onPressed: () async {
// Loader
String platForm = _jsHelper.getPlatformFromJS();
print("platForm ----------- $platForm");
}

And it will print the platform on which you are running this project.

Output:

platForm ----------- MacIntel

Now you can check other functions by downloading the GitHub project

I believe that you will check the demo and you will find the interesting part of Flutter Web with JavaScript communication.

I am always available for help if you get stuck anywhere.

Clap for Appreciation :)

Hope you like the article and learned something useful. Keep Clapping. 😄 👏

Connect with me on LinkedIn, Twitter and Don’t forget to follow me here for more updates.

Keep Sharing. Thank you 😅

--

--

Pratik Butani
7Span
Editor for

55k+ Reputation Holder on Stack Overflow | #FlutterDev & #AndroidDev | Team Lead @7Span | Contributor | Managing @androidschool