I just come across the concept of decorator and apply-call methods.
Why should I use an apply method here, even if it works without that. I can just pass "return func(...args)" and it still works. I understood the concept if I was working with an object method while having a returning this I should have used "apply" or "call",but why is it forwarding the call here with a function? On top of that, how the ".calls" property is getting passed to work.calls ?
function work(a, b) {
alert( a + b );
}
function spy(func) {
function wrapper(...args) {
wrapper.calls.push(args);
return func.apply(this, args);
}
wrapper.calls = [];
return wrapper;
}
work = spy(work);
work(1, 2);
work(4, 5);
for (let args of work.calls) {
alert( 'call:' + args.join() );
}
Related
The below code is generating errors:
Initialize:
var firstC = ["AUD","ZAR"];
var secondC= ["AUD","BRL","CAD","USD"];
function colorG(item, col, row){
var currency = firstC[col] + "-"+ secondC[row];
if(verifyCurrency(currency)==true)
item.getStyle().backgroundColor="green";
}
function verifyCurrency(currency)
{
if(this.getRowData().getExpressionValue("row[digital]").indexOf(currency)!=-1)
return true;
else return false;
}
cell:
colorG(this,1,0);
In which phase do I have to place verifyCurrency so that it will work?
Your assumption about "this" in your verifyCurrency function is wrong. I don't know Javascript good enough to tell you more about this, but I think that "this" is always defined inside a function. But it is not pointing to your item instance!
To fix this (no pun intended), pass the item as an argument to your verifyColor function.
I got a warning on the following piece of code, and I don't know why.
List<Map<String, int>> callNoInfo = [];
int getCallNo(String phoneNo) {
callNoInfo.forEach((item) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
});
return 0;
}
The warning is:
This function has a return type of 'int', but doesn't end with a return statement. (missing_return at [project_name] lib\helper\call_no.dart:35)
Can anyone tell me why this happens? thanks in advance
In the forEach method, you are creating a lambda function without explicitly defining the return type, so Dart is attempting to infer it from the return statements. If we pull the function out of the forEach method, it might help to see what I mean:
...
(item) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
}
...
The function includes a return statement that returns item[phoneNo], which is an int value. Using this, Dart infers that the return type of this lambda function is int. However, now that it knows this, it also notices that if the code execution does not enter the if block, there is no return statement to match the else side of the if condition. If the item object does not contain the key phoneNo, what is the method going to return?
(The answer is that the method will implicitly return null which is why the message is only a warning and not a compiler error, but the warning appears because this probably wasn't intentional by you the developer and also as a nudge to help you make your code less reliant on invisible Dart runtime magicks.)
To fix this, there needs to be another return outside of the if block:
...
(item) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
return 0;
}
...
However, now there's a different problem. The forEach method on lists has the following signature:
forEach(void f(E element)) → void
In fact, there are two problems. First, the method passed as the parameter needs to have a return type of void, and the forEach method itself also has a return type of void. This means that you cannot return values from within the forEach method at all.
The thing about the forEach method is that it is intended to iterate over the collection and process each of the values within it. It's not meant to (and can't) search for a value and return it once it's found. Furthermore, the iteration is exhaustive, meaning once you start it, the method cannot be stopped until each and every element in the collection has been iterated over.
Which is why, as the other answers have pointed out, what you really should be doing is using a for or for in loop:
List<Map<String, int>> callNoInfo = [];
int getCallNo(String phoneNo) {
for(var item in callNoInfo) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
}
return 0;
}
(I'm not sure why you don't get a compiler error for assigning a lambda function with a return value of int to the forEach method which clearly is requesting a one with a void return type. But if I had to guess, I'd say the Dart runtime treats them as compatible and reconciles the difference in return type by simply discarding the return value of the lambda function.)
You don't have an else case for the if statement inside the forEach loop. Even though you might have one at the end, it still is expecting a case everywhere.
List<Map<String, int>> callNoInfo = [];
int getCallNo(String phoneNo) {
callNoInfo.forEach((item) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
// you don't have a case for here since it's in a callback
});
return 0;
}
However, you could do this which uses a for in loop:
List<Map<String, int>> callNoInfo = [];
int getCallNo(String phoneNo) {
for (var item in callNoInfo) {
if (item.containsKey(phoneNo)) {
return item[phoneNo];
}
}
return 0;
}
I’m a newbie in programming language and I’m learning Javascript. I’m trying to understand the concept of callback function. I realized that callback is intended a function passed as parameter, but when does it call?
In the below examples I used a classic approach to write functions and then I tried to use the arrow function. The callback is done() function, in the first example it is called after the parent function, in the second one after.
What is the reason? Can you give me an explanation? Thank you so much for the feedback
Example no. 1
function done(){
console.log("Done");
}
function increment(num, callBack){
for(var i = 0; i <= num; i++){
console.log(i);
}
return callBack();
}
increment(10, done);
Example no. 2
const done = () => {
console.log("Done");
}
const increment = (num, done) => {
for (var i = 0; i <= num; i++) {
console.log(i);
}
}
increment(10, done());
To use callback you need to specify that there'll be a callback function as a argument, and you need to call that somewhere in the parent function like this, and that's when it will be called:
function someFunction(callback){
//Do something if needed...
callback() //callback(someParameter) if you want to pass some parameter to the callback func
//Do something if needed...
}
In your 2nd example, it's actually not a proper way of using callback function because you did not call the callback function inside parent function. You can modify it to to make it work as 1st example like this:
const increment = (num, done) => {
for (var i = 0; i <= num; i++) {
console.log(i);
}
done(); //call the callback function
}
increment(10, done); //just pass the name of callback func, not call it like you did "done()"
The below is my page object code
this.getRowBasedOnName = function (name) {
return this.tableRows.filter(function (elem, index) {
return elem.element(by.className('ng-binding')).getText().then(function (text) {
return text.toUpperCase().substring(0, 1) === name.toUpperCase().substring(0, 1);
});
});
};
the above function is called in the same page object in another function, which is
this.clickAllProductInProgramTypeBasedOnName = function (name) {
this.getRowBasedOnName(name).then(function (requiredRow) {
requiredRow.all(by.tagName('label')).get(1).click();
});
};
but the above code throws an error in the console as requiredRow.all is not a function
but when i do the following :
this.clickAllProductInProgramTypeBasedOnName = function (name) {
var row = this.getRowBasedOnName(name)
row.all(by.tagName('label')).get(1).click();
};
this works fine and clicks the required element.
But this.getRowBasedOnName() function returns a promise, which should and can be used after resolving it uisng then function. How come it is able to work by just assigning it to a variable?
When you resolve the result of getRowBasedOnName(), which is an ElementArrayFinder, you get a regular array of elements which does not have an all() method.
You don't need to resolve the result of getRowBasedOnName() at all - let it be an ElementArrayFinder which you can chain with all() as in your second sample:
var row = this.getRowBasedOnName(name);
row.all(by.tagName('label')).get(1).click();
In other words, requiredRow is not an ElementArrayFinder, but row is.
I'm writing a tinyMce plugin which contains a section of code, replacing one element for another. I'm using the editor's dom instance to create the node I want to insert, and I'm using the same instance to do the replacement.
My code is as follows:
var nodeData =
{
"data-widgetId": data.widget.widgetKey(),
"data-instanceKey": "instance1",
src: "/content/images/icon48/cog.png",
class: "widgetPlaceholder",
title: data.widget.getInfo().name
};
var nodeToInsert = ed.dom.create("img", nodeData);
// Insert this content into the editor window
if (data.mode == 'add') {
tinymce.DOM.add(ed.getBody(), nodeToInsert);
}
else if (data.mode == 'edit' && data.selected != null) {
var instanceKey = $(data.selected).attr("data-instancekey");
var elementToReplace = tinymce.DOM.select("[data-instancekey=" + instanceKey + "]");
if (elementToReplace.length === 1) {
ed.dom.replace(elementToReplace[0], nodeToInsert);
}
else {
throw new "No element to replace with that instance key";
}
}
TinyMCE breaks during the replace, here:
replace : function(n, o, k) {
var t = this;
if (is(o, 'array'))
n = n.cloneNode(true);
return t.run(o, function(o) {
if (k) {
each(tinymce.grep(o.childNodes), function(c) {
n.appendChild(c);
});
}
return o.parentNode.replaceChild(n, o);
});
},
..with the error Cannot call method 'replaceChild' of null.
I've verified that the two argument's being passed into replace() are not null and that their parentNode fields are instantiated. I've also taken care to make sure that the elements are being created and replace using the same document instance (I understand I.E has an issue with this).
I've done all this development in Google Chrome, but I receive the same errors in Firefox 4 and IE8 also. Has anyone else come across this?
Thanks in advance
As it turns out, I was simply passing in the arguments in the wrong order. I should have been passing the node I wanted to insert first, and the node I wanted to replace second.