5

I have the following functional javascript code to demonstrate what I want to achieve. It should output the object passed to the method, and then the value of the property "a".

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <script>
    window.theObjectCall = function(x) {
      console.log(x);
      console.log(x.a);
    }
  </script>
  <script src="main.dart.js" type="application/javascript"></script>
</body>
</html>

I have the following dart code, and it works, but "a" is not accessible as I expect.

@JS('window')
library whatever;

import 'dart:js';

import 'package:js/js.dart';

@JS('theObjectCall') // Accessing method getCurrentPosition from Geolocation API
external void theJsObjectCall(JsObject theObject);

void someJsCallWithObject() {
  var object = JsObject(context['Object']);
  object['a'] = 'xxx';
  theJsObjectCall(object);
}

Executing the below logs "undefined" in the console.

enter image description here

1 Answer 1

7
+50

You should define your objects separately as shown in sample below. The reason is javascript is opaque to dart classes including JSObject. As the documentation suggests its just a proxy for you to access a js ojects properties in Dart. I am not sure if you can use it.

However if you already know the structure of the object you want to pass then you can define an anomymous class with that structure and pass it the defined JS function. Then dart2js will take care of the conversion appropriately.

@JS('window')
library whatever;

import 'dart:js';

import 'package:js/js.dart';
import 'package:flutter/material.dart';

@JS('theObjectCall') // Accessing method getCurrentPosition from Geolocation API
external void theJsObjectCall(ObjectYouWantToSend theObject);

void someJsCallWithObject() {
  ObjectYouWantToSend oywts = ObjectYouWantToSend(a: 'xyz');
  theJsObjectCall(oywts);
}

@JS()
@anonymous
class ObjectYouWantToSend {
  external factory ObjectYouWantToSend({
    String a,
  });
  external String get a;
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Container(
          child: Center(
            child: FlatButton(
              onPressed: someJsCallWithObject,
              child: Text('Call The js Function.'),
            ),
          ),
        ),
      ),
    );
  }
}

You can find the code here in my repo.

This is how it looks when deployed. enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, the solution worked :) I owe you a beer 🤗

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.