I'm using the Laravel Mix Polyfill extension (https://laravel-mix.com/extensions/polyfill) with a Laravel and Vue.js project.
When I import vue-select into a Vue file, I get the following error in IE11:
Object doesn't support property or method 'includes'
This seems weird to me, as I assumed that the Polyfill extension was explicitly designed to polyfill these types of things in IE11, etc.
If I add the following block above my import statement for vue-select (credit to: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes#Polyfill), then everything works fine, but I would ideally not like to do this and just rely on the Polyfill extension to manage all of this for me:
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
if (search instanceof RegExp) {
throw TypeError('first argument must not be a RegExp');
}
if (start === undefined) {
start = 0;
}
return this.indexOf(search, start) !== -1;
};
}
The Polyfill extension is working properly for promises in IE11, so I'm assuming that it is installed and set up correctly in my project, but I'm wondering what's up with the String.includes method specifically.
Does anyone know? Thanks.
Edit #1: Here's what I have set for the polyfill method in the webpack.mix.js file:
.polyfill({
enabled: true,
useBuiltIns: 'usage'
});
Related
I know how to index an array with [] but I'm trying to display an item from an array based on its index using Array.at() method as described here MDN Docs - Array.at
But I get the following error:
Uncaught TypeError: arr1.at is not a function
I double-checked it, and everything is ok, however I don't know what's going wrong.
Here is my code:
const arr1 = [10, 20, 30, 40, 50];
const res = arr1.at(2);
console.log(res);
Note: This is different than the proposed duplicate of How to get value at a specific index of array In JavaScript?. That question is about methods for accessing an array, this question is why a new API for doing so is unavailable and how to rectify that.
If you get this message, whatever platform you're running the code on does not support the method yet. It's quite new - while the most recent versions of most browsers support it, anything before 2021 definitely won't. This method was only very recently signed off on (end of August 2021) and incorporated into the official specification, so it won't exist in older environments. Either upgrade your environment, or add a polyfill.
Per the proposal document, a "rough polyfill" that should be standards-compliant for most cases is:
function at(n) {
// ToInteger() abstract op
n = Math.trunc(n) || 0;
// Allow negative indexing from the end
if (n < 0) n += this.length;
// OOB access is guaranteed to return undefined
if (n < 0 || n >= this.length) return undefined;
// Otherwise, this is just normal property access
return this[n];
}
const TypedArray = Reflect.getPrototypeOf(Int8Array);
for (const C of [Array, String, TypedArray]) {
Object.defineProperty(C.prototype, "at",
{ value: at,
writable: true,
enumerable: false,
configurable: true });
}
Simply run that before trying to use .at, and you should be able to use it, even on older incompatible environments. You can also install this more exhaustive shim instead if you wish.
One option is to use the core-js library...
Modular standard library for JavaScript. Includes polyfills for
ECMAScript up to 2021: promises, symbols, collections, iterators,
typed arrays, many other features, ECMAScript proposals, some
cross-platform WHATWG / W3C features and proposals like URL. You can
load only required features or use it without global namespace
pollution.
First install it with npm or yarn:
npm install core-js
or
yarn add core-js
Then use it in your JS or TS project like this:
import 'core-js/features/array/at';
let arr = [];
arr.push(42);
console.log(arr.at(0));
Note that the code above only imports the at method for array. To import all polyfills or a subset:
// polyfill all `core-js` features, including early-stage proposals:
import "core-js";
// or:
import "core-js/features";
// polyfill all actual features - stable ES, web standards and stage 3 ES proposals:
import "core-js/actual";
// polyfill only stable features - ES and web standards:
import "core-js/stable";
// polyfill only stable ES features:
import "core-js/es";
If you're using node.js then please check the version of node.
It should be greater than 16.6.0. If not then update the node.js version.
Browser compatibility of Array.prototype.at()
The code is working fine in Stackoverflow code terminal. Your machine might not support the same due to JS versioning. The method is introduced recently.
I ran into this same issue when using Pipedream. I didn't realize that at() wasn't included in the NodeJS version they're using hinted at by Li Ki.
I implemented a similar solution proposed by Bjørnar Hvidsten; however, to get it to work in Pipedream, I simply added the following to the top of my NodeJS code.
import 'core-js'
const myArray = [1,2,3]
console.log(typeof myArray.at) // "function"
P.S. Referencing specific parts of core-js resulted in errors inside Pipedream, at least how I was trying to call it.
I'm currently trying to get a simple example running in which jQuery can be used by kotlin code compiled to JS with the help of gradle. So far I pieced together the following elements which should be enough according to older descriptions using the kotlin.js.externals:kotlin-js-jquery:3.2.0-0 package by adding it like this to the build.gradle.kts of the project:
repositories {
...
mavenCentral()
maven(url = uri("https://kotlin.bintray.com/js-externals"))
}
dependencies {
implementation("kotlin.js.externals:kotlin-js-jquery:3.2.0-0")
}
After adding the package I can sucessfully import the corresponding kotlin package in a simple Kotlin file like this:
import js.externals.jquery.jQuery
fun main() {
console.log(jQuery("div"))
}
But this sadly fails if executed with the following stack trace in the JS console:
Uncaught TypeError: $module$jquery is not a function
at main (simple.kt?9d2a:4)
at Object.eval (yet_another_one.js:14)
at eval (yet_another_one.js:5)
at eval (yet_another_one.js:8)
at Object../kotlin-dce-dev/yet_another_one.js (yet_another_one.js:515)
at __webpack_require__ (yet_another_one.js:30)
at Object.0 (yet_another_one.js:527)
at __webpack_require__ (yet_another_one.js:30)
at yet_another_one.js:94
at yet_another_one.js:97
After this I checked the packages webpack used for the bundling and I found out that as soon as the kotlin.js.externals:kotlin-js-jquery:3.2.0-0 package is used the following jquery.js file gets used instead of the one with the actual code:
(function (root, factory) {
if (typeof define === 'function' && define.amd)
define(['exports', 'kotlin'], factory);
else if (typeof exports === 'object')
factory(module.exports, require('kotlin'));
else {
if (typeof kotlin === 'undefined') {
throw new Error("Error loading module 'jquery'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'jquery'.");
}
root.jquery = factory(typeof jquery === 'undefined' ? {} : jquery, kotlin);
}
}(this, function (_, Kotlin) {
'use strict';
Kotlin.defineModule('jquery', _);
return _;
}));
//# sourceMappingURL=jquery.js.map
As this looks a bit strange to me as the jquery code seems not to be found anywhere I also tried adding it as a NPM dependency to the build.gradle.kts like this:
dependencies {
...
implementation(npm("jquery", "3.6.0"))
}
But doing so didn't change a thing. Webpack still uses the jquery.js file shown above (and maybe rightfully so), but it also still doesn't work.
I would appreciate any help to get this working as I already invested a lot of time in it and I'm currently kinda hopeless :(.
Thanks a lot!
To create a simple example, start a multiplatform project from the IntelliJ IDEA:
Select: File -> New Project
In the new window on the left hand select: Kotlin
In the main pane select the project template "Full-stack Web Application"
Use Build-System "Gradle Kotlin" to have best compatibility.
After this, Dukat is installed to generate your externals for jQuery:
Simply go to build.kts (your gradle build file) and under dependencies of jsMain add:
val jsMain by getting {
dependencies {
/// ... ommitted pre-installed directives
implementation(npm("#types/jquery","3.5.1", generateExternals = true))
implementation(npm("jquery","3.5.1"))
}
}
After this you can simply access jquery using jQuery as a static import:
import jQuery
And use it like a kotlin library: val xhr = jQuery.get("http://example.com")
I am using Angular 8, tslint 5.15 & typescript v3
I am reading file as ArryaBuffer using below code
const reader = new FileReader();
reader.readAsArrayBuffer(<FileObject>);
reader.onload = () => {
this.uploadedData= new Uint8Array(reader.result as ArrayBuffer);
}
Now when i pass this uploadedData into API, I am converting into byteArray using below fucntion.
convertLicenseToByteArray(uploadedData) {
const bytesArray = [];
for (const i of uploadedData) {
bytesArray.push(i);
}
return bytesArray;
}
The above code is giving error in ie11,
ERROR TypeError: Object doesn't support property or method
'Symbol(Symbol.iterator)_a.srxqdvyfxlx'
I tried to search on net and found that may be i need to add babel-polyfill but it's not working for me.
Any help?
add 'core-js' into you package.json and add import into your polyfills.ts
import 'core-js/es6/symbol';
IE11 doesn't support virtually any of ES2015+, so that means no arrow functions, no Symbol, and no iterables and iterators. (IE9-IE11 do support const and let, but not properly. They support an early version that isn't what was standardized. The biggest discrepancy is in regard to for loops.)
If you want to run that code on IE11, you'll need to transpile it to ES5 and add some polyfills. Symbol and iterability can't be properly polyfilled, but Babel and others provide something partially functional. I see here that Babel now recommends not using their own #babel/polyfill and instead using core-js directly (and regenerator runtime if you need to transpile generator functions).
The issue is relates to the uploadedData parameter, when we call the convertLicenseToByteArray method and use the uploadedData variable, if the data is not populated or undefined, it will display this error.
You could try to call the convertLicenseToByteArray method in the reader onload function.
const reader = new FileReader();
reader.onload = (_event) => {
this.uploadedData= new Uint8Array(reader.result as ArrayBuffer);
console.log(this.convertLicenseToByteArray(this.uploadedData).length);
}
For anyone that might be having this problem in an Aurelia project without typescript, I was able to solve it by installing core-js which included the polyfills needed to make this work.
npm install --save core-js#3.6.5
I then added the import in the .js file where I was having the issue and it started working.
import "core-js"
When running Sencha Cmd v6.5.3.6, i get the following error message:
[ERR] C2001: Closure Compiler Error (This code cannot be converted from ES6. extending native class: Array) -- compression-input:111263
The error is caused by this code:
class Chains extends Array {
}
The error still occurs with methods inside class declaration.
Is there a way to make this code compiled by Sencha Cmd ?
UPDATED :
To solve the problem, I change the code to:
function Chains() { };
Chains.prototype = new Array;
Chains.prototype.anyMethod = function () { }
You are using a feature of ES6 that cannot be transpiled into pre-ES6 code.
Sencha Cmd by default transpiles your code into pre-ES6 code because IE11 support has not yet been dropped.
You can disable code transpilation starting with Sencha Cmd 6.5.0 as described in the official docs:
There are cases where you won't need all that transpiling. Maybe you’re targeting Electron or you only support modern browsers that have all these features. You can disable the transpiler and still use the Sencha Cmd code compressor against your native ES6 code. Just a tweak to the app.json file and say goodbye to the transpiler and its polyfills:
"output": {
"js": {
"version": "ES6"
}
}
I don't think ExtJS supports that syntax as of now. For the time being, you might have to go with their syntax:
Ext.define('Chains', {
extend: 'Array'
});
Then in your code you can call it like this:
var chns = Ext.create('Chains');
chns.push('a');
console.log(chns);
I'm having trouble getting an npm module to work since it was changed to ES2015.
I have an ES2015 app that is bundled by browserify and transformed with babelify. I am trying to upgrade an npm module named credit-card for credit card validation, which was changed from ES5 to ES6 in the current version. The problem starts with IE11/Edge. The code works fine on Chrome. Here's how the module is imported in the transformed app (babel'd code):
var _this = this;
var _creditCard = require('credit-card');
var _creditCard2 = _interopRequireDefault(_creditCard);
Here's a piece of code calling it:
this.validateCreditCard = function () {
var ccNumber = _this.account_number_credit_card.value.replace(/\D/, '');
_this.creditCardValidation = {
accountHolder: _this.account_holder_credit_card.value.replace(/\W/g, '').length >= 2,
cvc: _this.account_cvc_credit_card.value.replace(/\D/g, '').length > 2,
accountNumber: _creditCard2.default.isValidCardNumber(ccNumber, _creditCard2.default.determineCardType(ccNumber, { allowPartial: true }))
};
return _underscore2.default.all(_underscore2.default.values(_this.creditCardValida tion));
};
Now on Chrome this works without a problem. On IE however, the exported functions of the credit card module are missing.
Here's a printscreen of a console log of the module in IE
And here's Chrome
It looks like defaults is completely missing in IE. Is this a known issue? Do any of you have encountered this problem before and can give me some hints? Any pointers on how I could investigate this issue to understand what is going wrong and how I could fix it?
Stepping through the require() in IE11 Debugger i found out that there was a problem with Object.assign being undefined in IE11. After some searching I found this thread. The answer in this thread worked out in the end. I needed to add polyfill to my browserify bundle and enable the "transform-es2015-classes" plugin with the opt loose: true (See this thread for code).