Search code examples
javascriptflutterdartflutter-web

Using the js library in the flutter project


I'm new to flutter, I have a flutter project that I'm building for android, ios and web. And only in the web build do I need to use the js library to encrypt api requests. Here is this library: https://www.npmjs.com/package/@expressms/smartapp-bridge and she's not very good, as far as I'm concerned. This is a requirement of the client and he provides this library. I can't rewrite it in dart. I have to use js callbacks for encryption and decryption in every api call. And I can't do it. I figured out what to use https://pub.dev/packages/js but it's too complicated for me. Maybe there is a good example with code?

@JS()
library web.js;

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:medlike/app.dart';


import 'package:js/js.dart';

@JS()
@anonymous
abstract class WebBridge {
  external void constructor();
  external factory WebBridge();
  external void addGlobalListener();
  external void enableLogs();
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);

  runApp(App());

  var bridge = WebBridge();
  print(bridge.toString());
}


Solution

  • I managed to cope with this problem, although it was not easy. It was necessary to wrap the response in promiseToFeature and allowInterop

    index.html

    <script>
            var bridge = window.webBridgeInstance;
            async function sendBotEvent(eventObject) {
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        resolve('done!');
                    }, 1500);
                    setTimeout(() => {
                        reject('err rejected!');
                    }, 2500);
                });
            }
    </script>

    api_client.dart

    @JS()
    library main;
    
    import 'dart:js' as js;
    
    typedef Callback<T> = dynamic Function(T arg);
    
    @JS()
    class Promise<T> {
      external Promise<T> then(Callback<T> successCallback,
          [Function errorCallback]);
    
      external Promise<T> catchIt(Function errorCallback);
    }
    
    @JS('sendBotEvent')
    external Promise<dynamic> sendBotEvent(Object objectParams);
    
    class SmartAppClient {
      Future<String> get(String endpoint, Object params) async {
        return await promiseToFuture(sendBotEvent({
          'method': 'get_$endpoint',
          'params': params,
        }).then(js.allowInterop((data) {
          print('SUCCESS: $data');
          return data;
        }), js.allowInterop((err) {
          print('ERROR: $err');
          return err;
        })));
      }
    }

    run:

    void testSmartappFuncs() async {
        await SmartAppClient()
            .get(
              'urlString',
              {},
            )
            .then((value) {
              print('RESULT RESULT RESULT');
              print(value);
            })
            .catchError((onError) {
              print('ERROR ERROR ERROR');
              print(onError);
            });
      }