I'm trying to get a customized built-in web component to work in codesandbox.io. This is the code:
class MyDiv extends HTMLDivElement {
constructor() {
super();
}
connectedCallback() {
this.innerHTML = "works!";
}
}
customElements.define("my-div", MyDiv, {extends: 'div'});
<div is="my-div"></div>
The error I'm getting:
Failed to construct 'HTMLDivElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
Tested in Chrome 67, Arch Linux. Here's the link: https://codesandbox.io/s/yqln560jzj
It does work here in a snippet, and it also works on codepen: https://codepen.io/connexo/pen/ZjEbqo
What am I missing here?
If it doesn't works it's because Codesandbox is using a kind a Javascript preprocessor (Typescript?) on external JS files, that will execute the code before (to detect syntaxt errors or so on).
The customElements.define() method is called twice, and fails the second time it is called because you can define a custom element only one time.
You can see it by calling customElements.get() inside your script, and see it's already defined.
console.log( customElements.get( 'my-div' ) )
If you put the Javascript inline (in the HTML file index.html) in a element it will work fine.
Note that the second error you get it's because you are using the Babel preprocessor in the Codeopen snippet. You must disable Babel and it will work.
What am I missing here?
Nothing. It's codesandbox.io that is missing Custom Elements support.
Related
My cross-platform vue app suddenly stopped working altogether on iOS 13, while still working just fine on iOS 14 and other platforms.
I added alerts to window.onerror and found out I have a case of TypeError: Reflect.construct requires the first argument be a constructor (only iOS 13) in my chunk-vendors.js file, where code is not really understandable.
I tried to revert package.json to a version from a commit where everything was still working, but that didn't help
A further look at chunk-vendors.js would eventually show you that the error is happening somewhere in babel's construct.js. To find out which class is causing the error, add a log/alert inside of _construct as such:
export default function _construct(Parent, args, Class) {
alert(Class); // <-- add this to find the culprit
if (isNativeReflectConstruct()) {
_construct = Reflect.construct;
} else {
...
Now it is time to revisit the constructor of the class, and more likely the constructors of the classes that it extends.
In my case, I had a class that extends EventTarget, which is not supported on iOS 13.
In short, I'm trying to call an external JS function which my 3rd party required me to include, in order to use their API, but doesn't work as it supposed to.
From what I've read, I am supposed to use, for example, window.extFn() after including the external JS in my index.html which contains the extFn() like so
<script src="https://example.com/external.js"></script> <-- actually not like this, see update 2 as I imported the library locally
...and supposed to use it like how it was answered here: Call external Javascript function from react components regardless of whether the said function is inside a file or simply defined on index.html <script> section. This had worked on the JS file I created for testing this.
//File: test.js
function test() {
return "Hello";
}
...imported the JS file with script tag like usual, and using console.log(window.test()) in my React Component's render() returned Hello.
I tried moving the import to HTML head from body and vice-versa but the error I'm still getting is:
TypeError: window.extFn is not a function
QuickCheckout.render
....
22 | }
23 |
24 | render() {
> 25 | window.extFn({
26 |
View compiled
▶ 20 stack frames were collapsed.
And when I look into my browser console, for some reason I have (which seems to be the key problem)
Uncaught SyntaxError: Unexpected token < external.js:1
Tried console.log(window.extFn) and it returns undefined
So I think it might be possible that the said JS is the problem itself, but I'm at my wit's end with this. Meanwhile I had emailed my 3rd party support team, does anyone have any advice on this? Thank you very much.
UPDATE: Now my test.js file above, which had worked in my experiment, produces the Unexpected token < error as well in my console...
UPDATE 2: I apologize for your problems. But I actually imported the JS from local source due to having to port their library as they had jQuery 2 instead of 3.
<script src="assets/js/external.js"></script>
And to my dumbness, i forgot the trailing /. Thank you for your help.
It seems that the path of external.js is wrong, which returns a html file instead of js file
you can check what the request of external.js returns at the "network" tab in chrome dev-tool
At the begining of file, before the class definition, please add
let extFn = window.extFn
then inside of component,you can use it.
extFn()//call inside component
I am new to typescript and am trying to get a simple class going. I have the below code and when I run, I keep getting a syntax error. I tried even an empty class and nothing.
I am using ASP.NET MVC5 (note, if I just have a function in the code, it works fine).
Inside Site.ts I have:
class Facebook {
constructor() { }
open() {
window.open("http://www.facebook.com");
}
}
var social = new Facebook();
I am calling the code by a link
open
I don't even get to click, right away, when loading I get
JavaScript critical error at line 1, column 1 in http://localhost:20870/Scripts/site.ts\n\nSCRIPT1002: Syntax error
It seems to work in the playground:
Click here to see my workout
Any ideas?
Looks like the browser is trying to execute the TypeScript and not the JavaScript. Double check your <script> tags (or any other thing you are using to load the code e.g. requirejs)
I had the same problem, when using a TypeScript tutorial on www.typescriptlang.org.
I realized that my script tag was referencing the TypeScript file and not the JS file:
<script src="greeter.ts"></script>
instead of:
<script src="greeter.js"></script>
I'm trying to a menu to the control bar of a video.js player via a plugin. Here's a demo of my end goal. The problem is that the demo is adding a menu to the control bar in video.js itself whereas I want a plugin that adds a menu.
So far I have been able to create a plugin that adds a MenuButton to the control bar, but I'm unable to populate the menu with any menu items.
Here's a demo of where I'm at now.
The problem is when I try to create a new PlaybackRateMenuItem object with new videojs.PlaybackRateMenuItem(this, {rate: rates[i] + 'x'}). The JS console throws the following error on line 805 of video.dev.js:
Uncaught TypeError: Cannot read property 'guid' of undefined
This corresponds to the following function in the unminified version:
vjs.bind = function(context, fn, uid) {
// Make sure the function has a unique ID
if (!fn.guid) {
fn.guid = vjs.guid++;
}
... omitted ...
};
Or more specifically, this line: if (!fn.guid) {.
From stepping through in a debugger, I see that fn is being passed in as undefined and the caller of the function is:
vjs.bind(this.player(), this.player().reportUserActivity);
When this function is being called, this.player() returns a defined value, but once vjs.bind is called, both arguments become undefined and I have no idea why. Any ideas or a point in the right direction? Thanks!
Turns out I had two major problems here.
Overriding the createMenu method instead of the createItems method for my class that extended the videojs.MenuButton class.
The this argument to the constructor of the videojs.MenuItem class must be the videojs player object, not just this. Problem is that the name of this object is mangled in the minified version of video.js. For this situation, I found that using this.c was the player object, but overall, I found it easier to just use the unminified version, video.dev.js, and not have to deal with the name mangling. In that case, using this.player_ was correct.
I'm using a jQuery plugin called toggleEdit for inline editing.
Everything works fine when the code is actually used in the page.
However, my test suite fails with the following error:
TypeError: Cannot call method 'remove' of undefined
I tracked it down to be triggered from within the clear method of this particular plugin. Its source file can be found here.
There are two relevant bits in that code:
1- The _init function
self.element.addClass("toggleEdit toggleEdit-edit toggleEdit-edit-" +
self._tag(self.element))
//store reference to preview element
.data("toggleEdit-preview", self.p);
As you can see, when the plugin is first instantiated it uses the data structure on self to store the newly created element.
2- The clear function
self.element.data("toggleEdit-preview").remove();
The clear function then tries to access that structure and retrieve the element. That's when, while inside a jasmine spec, it fails with the aforementioned exception.
Has anyone seen anything similar?
EDIT:
This is my spec, it's the simplest piece of code able to reproduce the error:
it("should update the given attribute on the server", function(){
$('#user-details input, #user-details select').toggleEdit(); //this line triggers the error
});
http://alz.so/static/plugins/toggleedit/jquery.toggleedit.js
I was taking a look at the source for toggleEdit and it seems that the only 2 times the function clear is called is just before self.element.data gets set:
if (typeof self.element.data("toggleEdit-preview") !== "undefined") {
self.clear();
self.disableEvents();
}
And at destroy function:
destroy: function() {
var self = this;
self.clear();
self.disableEvents();
$.Widget.prototype.destroy.apply(self, arguments);
}
Since the first call seems to be protected, I ask you a somewhat dumb question: Is it possible that destroy is being called twice?
Found my problem: old version of the jQuery + jQuery UI duo. Upgrading them resolves the exception.