MouseEventConstructor is not a constructor - javascript

When I execute my tests locally they pass with no problems but when tests proceed on the server I get:
TypeError: MouseEventConstructor is not a constructor (evaluating 'new MouseEvent('mousedown',
EXEC : error : TypeError: MouseEventConstructor is not a constructor (evaluating 'new MouseEvent('mousedown',
{
'which': 1,
'view': window,
'bubbles': true,
'cancelable': true
})')
for the code:
HTMLElement.prototype.mouseDownLeftButton = function () {
var event = new MouseEvent('mousedown',
{
'which': 1,
'view': window,
'bubbles': true,
'cancelable': true
});
this.dispatchEvent(event);
};
which is totally fine. Is there any other way to create a new MouseEvent ?

There is a polyfill from MDN that will resolve the issue:
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent#Polyfill
(function (window) {
try {
new MouseEvent('test');
return false; // No need to polyfill
} catch (e) {
// Need to polyfill - fall through
}
// Polyfills DOM4 MouseEvent
var MouseEvent = function (eventType, params) {
params = params || { bubbles: false, cancelable: false };
var mouseEvent = document.createEvent('MouseEvent');
mouseEvent.initMouseEvent(eventType, params.bubbles, params.cancelable, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
return mouseEvent;
};
MouseEvent.prototype = Event.prototype;
window.MouseEvent = MouseEvent;
})(window);

Most likely your local test infra uses real browser and on server it uses PhantomJS.
The latter still doesn't support new MouseEvent: https://github.com/ariya/phantomjs/issues/11289
I had to do the following trick to make tests pass:
function createMouseEvent(typeArg: string): MouseEvent {
let event = document.createEvent('MouseEvent');
event.initMouseEvent(typeArg,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined);
return event;
}

Related

How to dispatch a custom event?

How I could dispatch a custom event from '#input1' in this function?
What i tried:
export function captcha1_verified() {
$w('#input1').show();
const myEvent = new CustomEvent("myevent", {
detail: {},
bubbles: true,
cancelable: true,
composed: false,
});
$w('#input1').dispatchEvent(myEvent);
}
Error: TypeError: $w(...).dispatchEvent is not a function

Local function declaration versus pointer to function

class Testone{
constructor(value){
Object.defineProperty(this, 'doSomething', {
enumerable: false,
configurable: false,
writable: false,
value: () => {
//do whatever
}
});
}
}
const doWhatever = () => {
//do whatever
}
class Testtwo{
constructor(value){
Object.defineProperty(this, 'doSomething', {
enumerable: false,
configurable: false,
writable: false,
value: doWhatever
});
}
}
My thought is that Testtwo should be more efficient, since doWhatever would only exist in memory once then get pointed to by every instance of Testtwo. Testone would instantiate a new anonymous function for each new instance.
Does Testone actually create a new anonymous function each time? Is Testtwo therefor more efficient or is it also creating separate instances of doWhatever?
Am I missing some major caveat to one over the other (other than variable scope)?
My benchmarking consistently shows ~2% difference in instantiation time, with Testtwo indeed being faster... but that's not exactly confirmation.
Yes. Testone create new doSomething function every time, but Testtwo uses existing one.
Proof:
class Testone{
constructor(value){
Object.defineProperty(this, 'doSomething', {
enumerable: false,
configurable: false,
writable: false,
value: () => {
//do whatever
}
});
}
}
const doWhatever = () => {
//do whatever
}
class Testtwo{
constructor(value){
Object.defineProperty(this, 'doSomething', {
enumerable: false,
configurable: false,
writable: false,
value: doWhatever
});
}
}
const f1 = new Testone()
const f2 = new Testone()
console.log('Testone', f1.doSomething === f2.doSomething)
const s1 = new Testtwo()
const s2 = new Testtwo()
console.log('Testtwo', s1.doSomething === s2.doSomething)

How to set FileType on filestream

I'm trying to send a file stream from c# to my js backend. The name and path get send over correctly but the type seems to be missing when I log the file that enters my backend and I absolutely need the filetype but I can't figure out how to pass it with. can someone help me with this please?
object that comes in:
File {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
size: 13920,
path: '/var/folders/5g/f343vctd6hd7smyd5ybnfp4m0000gn/T/upload_4aebdbbee06344e12d8566dd706fd1e6',
name: 'Invoice19.pdf',
type: null,
hash: null,
lastModifiedDate: 2020-03-17T14:11:04.812Z,
_writeStream: WriteStream {
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: true,
needDrain: false,
ending: true,
ended: true,
finished: true,
destroyed: true,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: true,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object]
},
writable: false,
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
path: '/var/folders/5g/f343vctd6hd7smyd5ybnfp4m0000gn/T/upload_4aebdbbee06344e12d8566dd706fd1e6',
fd: null,
flags: 'w',
mode: 438,
start: undefined,
autoClose: true,
pos: undefined,
bytesWritten: 13920,
closed: false
}
}
my c# code
public IAsyncResult BeginExecute()
{
// set authentication
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", BearerToken);
string url = "http://12915520.ngrok.io/api/organisations/" + OrganisationId + "/projects/" + ProjectId + "/process";
string response = null;
bool succesfullRequest = false;
try
{
using (FileStream fs = File.Open(#"C:\Users\X Y\Downloads\Invoice19.pdf", FileMode.Open, FileAccess.Read))
{
// send the content to the backend, parse results
HttpContent content = new StreamContent(fs);
MultipartFormDataContent formdata = new MultipartFormDataContent();
formdata.Add(content, "files", "Invoice19.pdf");
var result = client.PostAsync(url, formdata).Result;
response = result.Content.ReadAsStringAsync().Result;
succesfullRequest = result.IsSuccessStatusCode;
}
}
// I absolutely want to catch every exception and pass these along to the workflow
catch (Exception ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
throw;
}
// if something went wrong in the backend, throw an error
if (!succesfullRequest)
{
throw new Exception("Something went wrong during the upload process");
}
UploadResponse r = JsonConvert.DeserializeObject<UploadResponse>(response);
Console.WriteLine("uploadresponse:" + r.ToString());
// dirty solution: since we don't know how long the pipeline needs to process the upload, we'll be polling for a result
// since this is a poc this is a temporary solution, if this gets released this needs to be rewritten (maybe with webhooks)
//var polling = true;
//do
//{
// response = client.GetAsync(url + "/" + r.uploadId).Result.Content.ReadAsStringAsync().Result;
// if (response != "null")
// {
// polling = false;
// }
//} while (polling);
// Because we know that there is a response now, actually execute the request
//return client.GetAsync(url + "/" + r.uploadId);
return null;
}
I believe that you need to change how you are using MultipartFormDataContent()
this works for me
using (var content = new MultipartFormDataContent())
{
content.Add(new StreamContent(stream)
{
Headers =
{
ContentLength = stream.Length,
ContentType = new MediaTypeHeaderValue([your content type])
}
}, "[name ex: file]", "[file name ex: file.jpg]");
}
I got it working by doing this:
MultipartFormDataContent formdata = new MultipartFormDataContent()
foreach (var filePath in Files.Get(context))
{
// create filestream content
FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
HttpContent content = new StreamContent(fs);
string name = GetFileName(filePath);
content.Headers.Add("Content-Type", GetFileType(name));
formdata.Add(content, "files", name);
}
// send content to the backend and parse result
var resultPost = client.PostAsync(url, formdata).Result;
response = resultPost.Content.ReadAsStringAsync().Result;
succesfullRequest = resultPost.IsSuccessStatusCode;
Basically, I set the content type of my inner content to whatever filetype it is and then set the content-type of my outer content to multipart/form-data (by adding it to the MultiPartFormData)
since I only support a limited amount of file types, I was able to write a simple function:
private string GetFileType(string name)
{
char[] charSeparators = new char[] { '.' };
var splitName = name.Split(charSeparators);
string extension = splitName[1].ToLower();
switch (extension)
{
case "pdf":
return "application/pdf";
case "png":
return "image/png";
case "doc":
return "application/msword";
case "docx":
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
case "txt":
return "text/plain";
case "tif":
return "image/tif";
case "jpg":
return "image/jpg";
case "rtf":
return "application/rtf";
// default == not supported type, we don't set content type
default:
return "";
}
}

Ext JS Hash Map not being destroyed after window closes

Basically just want to create a new hashmap once the window is closed because it currently will still have the old values after closing and rendering a new window.
data: {
classCheck: false,
hashTable: new Ext.util.HashMap(),
countValid: 0
}
listeners: {
afterrender: function() {
var scope = this;
window.addEventListener('resize', function() {
scope.updateWindow(scope);
});
this.on('close', function(scope) {
this.getViewModel().data.hashTable = new Ext.util.HashMap();
window.removeEventListener('resize', scope.updateWindow);
});
},
},
renderer: function(value, cell_field1, cell_field2, cell_field3) {
var hashmap = this.up('classroom').getViewModel().data.hashTable;
JavaScript uses prototyping to implement class inheritance. The windows are instances of a window class, and due to the nature of prototyping the window instances reference the properties defined on the class until an instance explicitly sets them.
Ext.define('Fiddle.Class', {
boolean: true,
object: {},
constructor: function() {
/* 1. Instance Prototype
{ {
boolean: true,
object: {}
} }
*/
this.boolean = false;
this.object.key = false;
this.object = {};
/* 2. Instance Prototype
{ {
boolean: false, boolean: true,
object: { key: true } object: { key: false },
instance: null
} }
*/
// This returns true.
return this.object.key;
}
});
Therefore, the window instances need to set the values of properties that are objects or arrays during initialization, so that each instance gets its own copy. This can be defined on the class, and it is usually done in the constructor so that the data is available as early as possible.
Ext.define('Fiddle.window.Window', {
extend: 'Ext.window.Window',
data: null,
constructor: function(config) {
this.data = {
classCheck: false,
hashTable: new Ext.util.HashMap(),
countValid: 0
};
this.callParent(arguments);
}
});

How do I undo a Object.defineProperty call?

Fiddle
var Assertion = function() {
return { "dummy": "data" };
}
Object.defineProperty(Object.prototype, 'should', {
set: function(){},
get: function(){
return new Assertion(this);
}
});
// Insert magic here.
// This needs to be false
console.log(({}).should === undefined);
What options do I have in ES5 to undo a defineProperty call ?
No silly suggestions like Object.defineProperty = function() { } please.
The following Object.defineProperty(Object.prototype, 'should', {})
does not work
and Object.defineProperty(Object.prototype, 'should', { value: undefined })
Throws a Uncaught TypeError: Cannot redefine property: defineProperty in V8
Object.defineProperty(Object.prototype, 'should', {
set: function() {},
get: function() { return undefined; }
});
Throws the same error
delete Object.prototype.should also does not work
In general, you can't undo a defineProperty call, since there's no undo stack or something. The JS engine does not keep track of previous attribute descriptors.
For example,
Object.defineProperty(Object.prototype, 'foo', {
configurable: true,
value: 1,
enumerable: false
});
Object.defineProperty(Object.prototype, 'foo', {
get: function () {
alert('You cannot revert me');
return 2;
},
enumerable: true
});
What you can do is remove or reconfigure an attribute, or overwrite its value. As mentioned in the other answer, the configurable flag is required to be true if you want to remove or reconfigure.
Once a property is defined with configurable:false, you cannot change the configurable flag.
To remove an attribute (this is supposedly what you want to do), use delete:
Object.defineProperty(Object.prototype, 'foo', {
configurable: true, // defaults to false
writable: false,
value: 1
});
delete Object.prototype.foo;
console.log(Object.prototype.hasOwnProperty('foo')); // false
To reconfigure, use defineProperty again and pass a different descriptor:
Object.defineProperty(Object.prototype, 'foo', {
configurable: true,
get: ...
set: ...
});
Object.defineProperty(Object.prototype, 'foo', {
value: undefined
});
console.log({}.foo); // undefined
console.log(Object.prototype.hasOwnProperty('foo')); // true
As shown in this sample, you can use defineProperty to switch between accessor (get/set) and data (value) properties.
To overwrite, use simple assignment. In this case, you need the writable flag to be true. Obviously this does not work with accessor properties. It even throws an exception:
Object.defineProperty(Object.prototype, 'foo', {
configurable: true,
value: 1,
writable: true // defaults to false
});
Object.prototype.foo = undefined;
console.log(Object.prototype.foo); // undefined
console.log(Object.prototype.hasOwnProperty('foo')); // true
Object.defineProperty(Object.prototype, 'foo', {
get: function () {
return 1;
},
writable: true // JS error!
});
Note that writable defaults to false when you use defineProperty, but true when you use the simple syntax o.attr = val; to define a (previously not existing) property.
If you want to undo your last defineProperty or all of them, you can use this class:
(gist here)
class PropertyDescriptorStack {
private readonly descriptors: PropertyDescriptor[] = [];
constructor(private readonly target: Object, private readonly prop: string) {
if (!target || typeof prop !== "string") { // your choice to define ""
throw new Error("PropertySaver: no object or property");
}
}
public push(props: Partial<PropertyDescriptor>): boolean {
this.saveDescriptor(this.target, this.prop);
try {
Object.defineProperty(this.target, this.prop, {
...props,
configurable: true,
});
return true;
}
catch (e) {
console.error(`Error setting property ${this.prop} on ${this.target}: ${e}`);
return false;
}
}
public pop(toStart?: boolean): boolean {
const ind = toStart ? 0 : this.descriptors.length - 1;
const descriptor = this.descriptors[ind];
if (!descriptor) {
return false;
}
this.descriptors.splice(ind, this.descriptors.length - ind);
try {
Object.defineProperty(this.target, this.prop, descriptor);
return true;
}
catch (e) {
console.error(`Error resetting property ${this.prop} on ${this.target}: ${e}`);
return false;
}
}
/**
* Saves the current descriptor of the property in the object in the descriptors stack.
* The descriptor is taken either from the object or from the closest prototype that has this prop.
* If none is found, a new descriptor is generated with the current value.
* #param target
* #param prop
* #returns The found descriptor
*/
private saveDescriptor(target: object, prop: string): PropertyDescriptor {
let ds: PropertyDescriptor | null = null;
for (let o: any = target, ds: PropertyDescriptor = null; o; o = Object.getPrototypeOf(o)) {
ds = Object.getOwnPropertyDescriptor(o, prop);
if (ds) {
break;
}
}
ds = ds || {
configurable: true,
writable: true,
value: target[prop],
enumerable: true
}
this.descriptors.push(ds);
return ds;
}
}

Categories