I was experimenting with generators for a bit. When I tried this piece of code I got unexpected errors:
Uncaught TypeError: Method [Generator].prototype.next called on incompatible receiver # or TypeError: CallStarGeneratorMethodIfWrapped method called on incompatible HTMLButtonElement
My question, does it not work ? What is the meaning behind those error messages ? And most importantly; Why is first().next not handled as a normal function ? Why does the addEventListener care about the origins of the first().next function. Type first().next in the console. It says function. Below is out commented a similar function to the next except it produces always the same result.
The code, that you can try to reproduce:
<html>
<button id="test">Click</button>
<script>
var first = function* (){
console.log("first click");
yield true;
console.log("second click");
yield true;
};
document.getElementById("test").addEventListener('click', first().next);
/*var wouldwork = function (){
console.log("would work");
return { value: true, done: false };
// same as the next returns
};*/
/*document.getElementById("test").addEventListener('click', wouldwork);*/
</script>
</html>
Another option would be to put next with the correct context in another function. To do that we store the iterator in a variable.
var iterator = first();
document.getElementById("test").addEventListener('click',
function (event){return iterator.next();}
//context of next is always the correct one
);
If that happens more often it can be a good idea to create a new function named createNext that returns a next function in a more pure functional style
var createNext = function (generatorFunction){
var iterator = generatorFunction();
return function() {
return iterator.next();
};
};
document.getElementById("test").addEventListener('click',
createNext(first)
);