Getting an arbitrary property from a JavaScript object in Dart
Ok, this was a fun one, happy holidays :)
It looks like Map
is not a supported auto-conversion for package:js
. So a couple of things:
- Filed https://github.com/dart-lang/sdk/issues/28194
- Sent your a PR introducing a workaround
For interested parties, we can use the browser-native Object.keys
:
@JS()library example;import 'package:js/js.dart';/// A workaround to converting an object from JS to a Dart Map.Map jsToMap(jsObject) { return new Map.fromIterable( _getKeysOfObject(jsObject), value: (key) => getProperty(jsObject, key), );}// Both of these interfaces exist to call `Object.keys` from Dart.//// But you don't use them directly. Just see `jsToMap`.@JS('Object.keys')external List<String> _getKeysOfObject(jsObject);
And call it once we have an arbitrary JavaScript object:
var properties = jsToMap(toy.getData());print(properties);
I had to modify @matanlurey solution so it works on dart 2.12 and is recursive.
import 'dart:js';/// A workaround to deep-converting an object from JS to a Dart Object.Object jsToDart(jsObject) { if (jsObject is JsArray || jsObject is Iterable) { return jsObject.map(jsToDart).toList(); } if (jsObject is JsObject) { return Map.fromIterable( getObjectKeys(jsObject), value: (key) => jsToDart(jsObject[key]), ); } return jsObject;}List<String> getObjectKeys(JsObject object) => context['Object'] .callMethod('getOwnPropertyNames', [object]) .toList() .cast<String>();