how to add extensions to dart js facades

Issue

I am trying to add showOpenFilePicker to Window object.

  @JS()
library js_t;

import 'dart:html';

import 'package:js/js.dart'; 

@JS("window")
abstract class _Window2 {
  external dynamic showOpenFilePicker();
}
    
extension WindowExt on Window {
      Future<dynamic> showOpenFilePicker() {
        Object t = this;
        final _Window2 tt = t;
        return promiseToFuture(tt.showOpenFilePicker());
      }
 }
 final r = await window.showOpenFilePicker();

I am getting following error

errors.dart:187 Uncaught Error: Expected a value of type ‘JSObject<>’,
but got one of type ‘Window’
at Object.throw_ [as throw] (errors.dart:233)
at Object.castError (errors.dart:84)
at Object.cast [as as] (operations.dart:442)
at dart.LegacyType.new.as (types.dart:445)
at Object.WindowExt$124showOpenFilePicker [as WindowExt|showOpenFilePicker] (js_t.dart:36)
at main$ (main.dart:12)

Solution

This one worked for me

extension WindowExt on Window {
  @JS("window.showOpenFilePicker")
  external dynamic _showOpenFilePicker();

  Future<dynamic> showOpenFilePicker() {
    return promiseToFuture(_showOpenFilePicker());
  }
}

Edit :

but from docs

/// An annotation that indicates a library, class, or member is implemented
/// directly in JavaScript.
///
/// All external members of a class or library with this annotation implicitly
/// have it as well.
///
/// Specifying [name] customizes the JavaScript name to use. By default the
/// dart name is used. It is not valid to specify a custom [name] for class
/// instance members.
class JS {
  final String? name;
  const JS([this.name]);
}

It is not valid to specify a custom [name] for class
/// instance members.

:s

Edit2 :

js_utils to the rescure

extension WindowExt on Window {
 Future<dynamic> showOpenFilePicker() {
    final Object t = this;
    return promiseToFuture(callMethod(t, "showOpenFilePicker", []));
  }
}

Answered By – invariant

Answer Checked By – Mary Flores (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *