Dart VM version: 2.7.1
MacOS Catalina 10.15.3
Firefox Nightly 75.0a1
I was making a very simple web app, and while it had no errors when served using webdev serve, after using webdev build and serving the production files, I get the following error in the console.
: TypeError: Instance of 'bG': type 'bG' is not a subtype of type 'minified:k'
I've tried using Chrome and had no problems. And I booted up an Ubuntu machine I have with normal Firefox installed and had no problems there either.
This is the repository where I'm having the problem: https://github.com/mcaubrey/simple_dart_weather
I realize this could just be a problem with Nightly, and I'll try to make bug report on Bugzilla.
@mcaubrey one thing to try is to try disabling minification in dart2js, that will make he error a bit easier to understand and might give some clues on what could be happening.
webdev has these options to override the default compiler: https://github.com/dart-lang/build/blob/master/docs/faq.md#how-can-i-debug-my-release-mode-web-app-dart2js
When running webdev-build the compiler is already dart2js, but I believe that by overriding it, you'll keep using dart2js but it will no longer include any flags (by default it passes --minify and a couple other flags).
Hope this helps and keep us posted!
So I tried setting up a build.yaml file as described in the link you provided, and it did not automatically override the minification.
However, I found this suggestion for disabling minifcation and tried that.
After turning off minify, I no longer get the TypeError at all.
Here's a working example of page throwing the TypeError. Again, I've only been able to get it to throw an error on Firefox Nightly. On Chrome and regular old Firefox it works fine: https://www.michaelcharl.es/aubrey/sample/
The error is thrown when you enter a city name and press the button.
FirefoxNightly dispatches the form submit event with SubmitEvent, that seems not to be handled in dart.
added by https://bugzilla.mozilla.org/show_bug.cgi?id=1588715
the example code receives the parameter with Event type:
https://github.com/mcaubrey/simple_dart_weather/blob/a2137f19c1f5152798d85099966d86869eca8fe1/web/main.dart#L10
and it looks like SubmitEvent isn't treated as a subtype of Event.
If I add SubmitEvent to the object passed to hunkHelpers.setOrUpdateInterceptorsByTag call, in generated code in https://www.michaelcharl.es/aubrey/sample/main.dart.js
the issue doesn't happen.
prettified code below:
hunkHelpers.setOrUpdateInterceptorsByTag({
...
Event: W.k,
SubmitEvent: W.k, // <-- added here
InputEvent: W.k,
...
})
so, it sounds like, the inheritance isn't handled properly for unknown interface.
The same issue happens also on Chrome Canary, that also implements SubmitEvent.
I've updated the title to reflect what @aria-a found.
Thanks for all the detail feedback.
I'm surprised to hear that you didn't see the error without minification. Looking at the link, it appears the suggestion also included -O4, did you include that one too? If so, that would explain it (starting with -O3 the compiler elides type checks assuming they don't occur). If you remove that flag or use -O2, I believe you'll see the error.
If the error shows with -O2, I presume the issue is because this new event is not yet visible to our dart:html library.
/cc @srujzs @rakudrama - given that we are unlikely going to roll the IDL that soon, I wonder if there is a workable workaround here. Either something we can add/expose in dart:html or a hook users can access externally (e.g. amending getTag like we used to do for the webcomponents polyfill). What are your thoughts?
IIUC, the IDL and therefore dart:html doesn't have the SubmitEvent native class. I think we should look into adding this onto dart.idl to support it. Re: your latter suggestion about adding a hook -- what would that look like?
can you just walk up the prototype chain and look for known interface (prototype) that matches the variable/parameter type?
otherwise the compiled code will break every time new sub-interface like SubmitEvent is added.
@sigmundch You're correct, I included the -04. I didn't know what it did.
@sigmundch
I can confirm that after removing the -04 I start getting the type error again.
: TypeError: Instance of 'UnknownJavaScriptObject': type 'UnknownJavaScriptObject' is not a subtype of type 'Event'
Can you check, by breakpointing the generated non-minified JavaScript, what the object is, and what is on the prototype chain? The spec link says interface SubmitEvent : Event, so if it is the Browser's SubmitEvent, it should have Event.prototype on the prototype chain.
If it does, then it should look like an Event to dart.
I don't have non-minified code, so testing with minified+prettified code.
when reporting TypeError, given the object in variable a,
Object.getPrototypeOf(a) is SubmitEventPrototype, that is SubmitEvent.prototypea.constructor and Object.getPrototypeOf(a).constructor is SubmitEventObject.getPrototypeOf(Object.getPrototypeOf(a)) is EventPrototype, that is Event.prototypeObject.getPrototypeOf(Object.getPrototypeOf(a)).constructor is EventSo, if the code walks up the prototype chain, it should find Event prototype and constructor
then, where's the code that walks up the prototype chain?
at least by looking the minified code, I cannot locate such code,
but it just checks typeof, constructor, and the prototype of the value itself.
So - what now? SubmitEvent just landed into both Chrome and Firefox. And because I handle forms in AngularDart like this
<form (submit)="doSomething($event)">
void doSomething(Event e) { /// <--- this fails, SubmitEvent is not an event
e.preventDefault();
// ... some REST here ....
}
All my apps are broken. I mean ... all of them. Is there at least some workaround?
There is a hook for mapping unknown 'native' classes to existing 'native' classes.
Put this in your html file ahead of the script tag that loads the dart app:
<script>
if (typeof dartNativeDispatchHooksTransformer == "undefined") dartNativeDispatchHooksTransformer=[];
dartNativeDispatchHooksTransformer.push(
function(hooks) {
var getTag = hooks.getTag;
var quickMap = {
"SubmitEvent": "Event",
};
function getTagFixed(o) {
var tag = getTag(o);
return quickMap[tag] || tag;
}
hooks.getTag = getTagFixed;
});
</script>
What it does is make a SubmitEvent appear to the Dart program as a plain Event.
@srujzs We can change the dart:html library to do something similar automatically.
@rakudrama Thanks! I'll try it right away.
What about Dart 1, is there a similar possibility or maybe even the same piece of code?
@rakudrama Ok, it works even in old-dart-1-pub-build-based projects. Thanks again, you saved a lot of a....s today :-)
@srujzs 鈥撀燾an we call this fixed?
It addresses the issue but it isn't an ideal fix. I think any other fix on the dart2js side should spawn its own separate bug to address this and similar issues, so I'm fine with it being marked fixed.
Most helpful comment
There is a hook for mapping unknown 'native' classes to existing 'native' classes.
Put this in your html file ahead of the script tag that loads the dart app:
What it does is make a
SubmitEventappear to the Dart program as a plainEvent.@srujzs We can change the dart:html library to do something similar automatically.