Is there Lambda support in QML files? - javascript

I have something like this:
var arr = []
arr.indexOf(element => element.includes(''))
QtCreator gives error for this. My Qt version is 5.12 and I'm using QtCreator 4.8.
Can I use this kind of lambda expressions in QML?

That was just a QtCreator bug, arrow functions are supported in Qt 5.12 and later. QtCreator properly supports them starting 4.9 version and stop displaying warnings for it (QTCREATORBUG-21301 & QTCREATORBUG-20341. See 4.9 changelog).
In your case however, as folibis said, you need findIndex if you want to provide a predicate. It does work in 5.12, the page of the supported functions is not very reliable.
Qt 5.12 should support most of the standard ECMAScript functions, look at MDN for reference and try it your Qt code.
{
let arr = ['a', 'ab', 'abc', 'abcd'];
let index = arr.findIndex(element => element.includes('c'));
let abcIsPresent = arr.includes('abc');
print(index, abcIsPresent);
}
This codes runs in Qt 5.12 and outputs 2 true.

Related

Unexpected token: operator (>) when trying to minify the javascript?

I'm trying to minify my javascript code using an online tool but everytime I try to do that I get this error:
// Error : Unexpected token: operator (>)
// Line : 1
// Col : 41
and this is on line 1:
var result = parsedObject.filter( audio => audio.filename === ''+audioFile+'' );
Could someone please advice on this issue and how to resolve it?
Thanks in advance.
Apparently, your minifier doesn't understand arrow functions, or it needs some option to be set to know you're doing ES2015+ ("ES6+") stuff. Your options are:
If it has an option, turn the option on; or
(you've now told us that you tried both https://jscompress.com/ and https://javascript-minifier.com/. jscompress.com has an "ECMAScript 2018 (via Babili)" tickbox in the upper right-hand corner that, when ticked, minifies your example code. I didn't find an option on javascript-minifier.com.)
If it doesn't, switch to a mninifier that does understand them; or
Don't use arrow functions. In this particular case that would look like:
var result = parsedObject.filter(function(audio) {
return audio.filename === ''+audioFile+'';
});
Use arrow function, but turn them into non-arrows before minifying by using a transpiler like Babel.
If you need to support any version of IE, you need to not send arrow functions to the browser (by using option 3 or 4 above). If you don't have to support IE, just modern browsers like Edge, Chrome, Firefox, and Safari, sending arrow functions to the browser is just fine.
Side note: You don't need those '' on either side of audioFile. If it's already a string, just remove them (=== audioFile). If it isn't already a string, just do one or the other, or use String(audioFile) to convert it, and do it once before the filter loop:
var audioFileString = String(audioFile); // or `'' + audioFile` or `audioFile + ''`
var result = parsedObject.filter(function(audio) {
return audio.filename === audioFileString;
});
The tool you are using does not support arrow functions (which are a relatively new feature).
You can:
Find a minifying tool which supports modern JS
Not use arrow functions in the first place
Use a tool to transform your JS to ES5 before minifying it

Underscore js syntax error in IE 11

I am using the underscore js library (http://underscorejs.org/#filter) for functionality in my app.
Everything works as expected in chrome. However when I run the same code in IE11 I get an js error in the console
SCRIPT1002: Syntax error
File: OptionSrv.js, Line: 197, Column: 62
When I clicked the file to bring me to the error the cursor is placed on the => - is this a red herring or should there be another way of doing this which works in both chrome and IE?
Note if I comment out the line in IE I don't get the console error however this obviously isn't the fix that I need
var group = myOptions.filter(g => g.options.indexOf(option.OptionCode) > -1);
Internet Explorer 11 does not support arrow functions.
That's the g => g.options.indexOf(option.OptionCode) > -1 part of your code.
You can use a normal anonymous (or named) function instead here, and it should work fine:
var group = myOptions.filter(function(g) {
g.options.indexOf(option.OptionCode) > -1);
});
IE11 does not support ES6 syntax. If you want to write ES6 syntax like Arrow functions, you can run your code through a transpiler like Babel.
If you like your client-side code to be compatible with older browsers and you don't care about new syntax, simply use ES5 syntax :)

having trouble with JavaScript spread syntax

I just read the MDN page for the ES6 spread syntax, and most of the examples on the page worked, but the last one did not:
var obj = {"key1":"value1"};
function myFunction(x) {
console.log(x); // undefined
}
myFunction(...obj);
var args = [...obj];
console.log(args, args.length) //[] 0
I tried it in both Chrome and Firefox, and I'm running the latest browser versions, so the page says that the code ought to work.
Can anyone tell me what the problem is?
The issue is most likely that using the spread syntax with objects isn't currently supported with browsers. Doing something like this:
let inventory = {
apples: 3,
oranges: 4
}
let updatedInventory = {
...inventory,
grapes: 4
}
console.log(updatedInventory)
should print out this:
{"apples":3,"oranges":4,"grapes":4}
but as you can see, the browsers are throwing an error. If I recall correctly, object-spread was an ES7 proposal while array spreading was an ES6 one which is probably why object-spreading hasn't been fully implemented yet.
To try out the latest ES6/ES7 stuff that hasn't been implemented yet, you can use the online REPL provided by Babel. It's cool because you can see the equivalent ES5 code output on the right side.
If you put the above code example in the repl, you'll see the correct console output (on the bottom right).

Does Javascript have an enhanced for loop syntax similar to Java's

I am wondering if JavaScript has an enhanced for loop syntax that allows you to iterate over arrays. For example, in Java, you can simply do the following:
String[] array = "hello there my friend".split(" ");
for (String s : array){
System.out.println(s);
}
output is:
hello
there
my
friend
Is there a way to do this in JavaScript? Or do I have to use array.length and use standard for loop syntax as below?
var array = "hello there my friend".split(" ");
for (i=0;i<array.length;i++){
document.write(array[i]);
}
JavaScript has a foreach-style loop (for (x in a)), but it is extremely bad coding practice to use it on an Array. Basically, the array.length approach is correct. There is also a a.forEach(fn) method in newer JavaScripts you can use, but it is not guaranteed to be present in all browsers - and it's slower than the array.length way.
EDIT 2017: "We'll see how it goes", indeed. In most engines now, .forEach() is now as fast or faster than for(;;), as long as the function is inline, i.e. arr.forEach(function() { ... }) is fast, foo = function() { ... }; arr.forEach(foo) might not be. One might think that the two should be identical, but the first is easier for the compiler to optimise than the second.
Belated EDIT 2020: There is now for (const item of iterable), which solves the downsides of using for (item in iterable).
Using the latest versions of JavaScript available to most modern browsers, you can do this:
array.forEach(function(x){
document.write(x);
});
Details are at https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach. If you're worried that a browser may not have support for this, you can add it yourself, using a (hopefully minified) version of the implementation that they have listed under "Compatibility".
This is a bit outdated, but this is a minified compatibility version of forEach that I derived from Mozilla's page a few years ago:
if(!Array.prototype.forEach){Array.prototype.forEach=function(b){if(typeof b!="function"){throw new TypeError()}var a=this.length,d=arguments[1],c;for(c=0;c<a;c++){if(c in this){b.call(d,this[c],c,this)}}}};
I've never run into any issues with this, but the implementation on Mozilla's page has since been expanded with some additional checks and code to make it compatible with ECMA-262, Edition 5, 15.4.4.18.
I have a file called common.js that I use and include on all of my pages to include this, as well as all of the other "Array extras" that were introduced with JavaScript 1.6, as listed at https://developer.mozilla.org/en/JavaScript/New_in_JavaScript/1.6#Array_extras. (I've been meaning to get this updated and published for public use.)
This may not be the fastest approach (see http://jsperf.com/for-vs-foreach/15 for some specifics - thanks for the link, Amadan) - but there is something to be said for conciseness and maintainability, etc. Additionally, it'll be very interesting to see how much of this disparity is optimized away by further JavaScript engine improvements over the next few months and years. :-)
In ES2015(ES6), you can use the for-of loop. It's supported in most browser with the exception of IE.
let array = [10, 20, 30];
for (let value of array) {
console.log(value);
}
See the Mozilla explanation here
You can do for(s in array), but be careful, it's not the same as a foreach.
In this case s is the key (index), not the value. You also need to use hasOwnProperty because in loops though the object's prototype also.
for(s in array){
if(array.hasOwnProperty(s)){
console.log(array[s]);
}
}
EDIT: As #Amadan pointed out, hasOwnProperty does iterate properties when they're added like this: array.test = function(){}. I suggest not using for...in.
EDIT2: If your using a modern web browser (anything that isn't IE < 9), you can use Array.forEach). #ziesemer points out that Mozilla has a shim for this if you need to support IE < 9.
array.forEach(function(s){
console.log(s);
});
NOTE: Personally I use jQuery for my JavaScript projects, and I use $.each.
$.each(array, function(i,s){
console.log(s);
});
There's the "forEach" method on the Array prototype in newer JavaScript engines. Some libraries extend the prototype themselves with a similar method.
Try this:
var errorList = new Array();
errorList.push("e1");
errorList.push("e2");
for (var indx in errorList) {
alert(errorList[indx]);
}
x = [1,2,3];
for (i in x) {
console.log(i);
}

Possible to assign to multiple variables from an array?

Is it a standard way to assign to multiple variables from an array in JavaScript?
In Firefox and Opera, you can do:
var [key, value] = "key:value".split(":");
alert(key + "=" + value); // will alert "key = value";
But it doesn't work in IE8 or Google Chrome.
Does anyone know a nice way to do this in other browsers without a tmp variable?
var tmp = "key:value".split(":");
var key=tmp[0], value=tmp[1];
Is this something that will come in an upcoming JavaScript version, or just custom implementation in FF and Opera?
Destructuring assignment was standardized in ECMAScript 2015 (a.k.a. ES6). But not all browsers have implemented destructuring yet (as of March 2016), and even when they do it will take a while before users update to a browser with support. See examples in the spec for all the awesome things you can do. Here are some:
// Assign from array elements
var [key, value] = "key:value".split(":");
// key => 'key'
// value => 'value'
// Assign from object properties
var {name: a, age: b} = {name: 'Peter', age: 5};
// a => 'Peter'
// b => 5
// Swap
[a, b] = [b, a]
// a => 5
// b => 'Peter'
Because this feature breaks backwards compatibility, you'll need to transpile the code to make it work in all browsers. Many of the existing transpilers support destructuring. Babel is a very popular transpiler. See Kangax´s table of browser and transpiler ES6-support.
More info:
Compatibility table for ES6 browser support
Exploring ES6 - Destructuring chapter
If you want to know what's coming, read the section on Destructuring Assignment.
https://developer.mozilla.org/en/New_in_javascript_1.7
What language features you can use is always dependent on your environment.
Developing for Mobile Safari (or a web stack for other browsers like the Palm Pre, Android, etc.) or AIR, for example, is more predictable than developing for the web at large (where you still have to take even IE6 into account).
A cross-browser solution to the problem at hand would be to initialize an array that had a list of the variables you want to fill in window.variable format, then just loop through. Can't imagine why you'd do it though. Seems like there would always be a better solution.
Use destructuring assignment, a feature of ES6:
var [x, y] = [1, 2];
console.log(x, y); // 1 2
I just had exactly same question, and as an exercise for myself came up with the following:
var key, value;
(function(arr){
key=arr[0];
value=arr[1];
})("key:value".split(":"));
alert(key + "=" + value);
Looks ugly to me, I'd rather use temp var (technically, I'm using here a temp variable anyway).
Edit: chrome supports that now. As for IE8: do we still care about it?
I don't think this is possible in a cross browser way. The best that I know which might help in a few circumstances is this:
// we'll pretend you don't need the key.
var value = "key:value".split(":")[1];
I think it should be a part of the new spec., then again it's a long read... :p
key = "key:value".split(":")[0];
value = "key:value".split(":")[1];
Only alternative I can think off.
I don't know how you are using this, but if I was able to determine my own format for the "key:value" string, I'd be tempted to use json to just eval the string into the necessary object:
var obj = eval("{'key':'key_str', 'value':'val_str'}");
alert(obj.key + "=" + ojb.value); //alerts "key_str=value_str

Categories

Resources