Dynamically adding event listeners by name - event-handling

How would you translate this function from Javascript into Dart?
function addEvtListener(Element el, evtName, fn) {
return el.addEventListener ? el.addEventListener(evtName, fn, false) : el.attachEvent('on' + evtName, fn);
}
The main issue is having the event name dynamic. I obviously can call:
el.onClick.listen((event) => fn(event));
if the evtName is a click event. But is there a method like this in Dart?
el.on("click").listen(event) => fn(event));

The Events class documentation has an overview of the different ways to listen for an event by name: http://api.dartlang.org/docs/releases/latest/dart_html/Events.html
You'll see that you can do both:
new EventStreamProvider(evtName).forTaget(el).listen(fn);
or
el.on[evtName].listen(fn);

You can use :
(const EventStreamProvider<Event>(evtName)).forTarget(el).listen((e) => fn(e));

Related

Flutter - Parameter Type for a Method

I am working a FLUTTER project and need to write a method (or maybe a function). One of the parameters in the method needs to be an expression like:
PlayList videos = videoList[index] as PlayList
Is it possible? If so what type should I should use.
typedef can set the data type, method parameters
typedef ProcessCallback = PlayList Function();
set as method parameter
void foo(ProcessCallback callback) {
/// result type is PlayList
var result = callback.call();
}
when calling the foo method
ProcessCallback callback = () => videoList[index] as PlayList;
foo(callback);
Before actually running the callback.call() method, it is just a data type:
Closure: () => PlayList
.call() can also be replaced with ();

Why is lambda expression used in DOTween?

I'm using a lambda expression in my C# script in my Unity project to call a function with a parameter when a DOTween callback is called.
It simply looks like this: animation.OnComplete(() => DestroyOnCompleted(children));
It works just fine, but I am note sure why a lambda expression is used in this case. I know it has something to do with delegates, but other than that, I'm not too sure; and I would like to explain it to my exam, if I get asked about it.
Could anyone enlighten me? :-)
Why not? ;)
I don't know that API too much but it seems like it is simply expecting something like
OnComplete(TweenCallback callback)
where TweenCallback from your usage basically seems to equal the c# built-in Action delegate and basically simply a parameter less void
public delegate void TweenCallback();
so whether you pass in this callback as a lambda like
animation.OnComplete(() => DestroyOnCompleted(children));
or anonymous method using the delegate operator like
animation.OnComplete(delegate { DestroyOnCompleted(children); });
or using a method
animation.OnComplete(OnCompletedAnimation);
...
private void OnCompletedAnimation()
{
DestroyOnCompleted(children);
}
is basically equivalent.
The main difference between the first two and the last one is: Where does children come from?
The lambda and delegate way allows you to pass in children from the current scope variables without having to store it in any field!
If you look at the documentation of DotTween, you see that row:
Now looking at the Source Code of DotTween, you can see the definition of TweenCallback:
public delegate void TweenCallback();
So the question now is, what is a delegate void in c#?
A delegate in c# is basically an object that "represent" a function.
But functions are not all the same, they can have parameters in input and return something (or return void).
To understand what kind of function does a delegate represent, try to just remove the keyword delegate.
For example, the TweenCallback without the keyboard delegate is:
public void TweenCaalback()
So the delegate represent a void function that has no parameters in input! (And it is Public).
What does it means represent a function?
It means that this is valid code:
void DoNothing()
{
}
TweenCallback x = DoNothing;
x();
So you can "assign functions" to a delegate that has the same function signature.
In this case, TweenCallback is a delegate void (), so you can assign to it a void() function.
What is a lambda?
A lambda is an expression of that style:
(string name, int age) => { return 3 };
you can read that as "string name and int age go in return 3"
That's a more concise way to describe that function:
int AnonymousFunction (string name, int age) {}
The main difference is that lambdas do not have any name. If you have not any parameter in input the lambda become like this:
() => {return 3;}
If you have only one statement inside the {} you are allowed to write it more shortly as
() => 3;
Final step
Is this valid code?
void DoNothing()
{
}
TweenCallback x = () => DoNothing();
Yes it is! Tween callback is expects a void () function.
() => DoNothing(); Is a lambda (un-named function) that takes nothing in input and calls some other function. It's the shorter version of () => {DoNothing();} that you have to think as void () {DoNothing();}
So when writing
animation.OnComplete(() => DestroyOnCompleted(children));
You are just passing a void () function to OnComplete Method, that makes sense because TweenCallback is a void () delegate.
Notes
As you can see, functions and lambdas expression can be converted implicitly to delegates. But you have to understand that they are all different things, and in more advanced coding scenarios that distinction is not just pure theory.

Where is the documentation to write an event handler for input text box?

Originally I wanted to know:
How do I write a handler for this?
type state = string;
type action = | ChangeName(string)
let reducer = (_state, action) => switch action { | ChangeName(text) => text }
[#react.component]
let make = () => {
let (state, dispatch) = React.usefReducer(reducer, "");
/* What is the parameter type and how do I decode it? */
let onChange = ??? => dispatch(ChangeText(????));
<input value=state onChange/>
}
Specifically, what is the parameter type for the punned onChange handler and how do I decode it?
Every reference I come across is for JS, which I'm having difficulty translating to Re.
EDIT
The answer I found by scraping github:
let onChange = event => dispatch(ChangeName(ReactEvent.Form.target(event)##value));
Say I'd like to use another JSX element, where's the documentation? OR, is their a supposition that people coming to this from elsewhere have knowledge apriori? (I'm mostly comfortable with 'c').
You can get the types of all the DOM attributes from https://github.com/rescript-lang/rescript-react/blob/v0.10.1/src/ReactDOM.res
This file contains bindings to ReScript-React's subset of DOM attributes. It has:
onChange: ReactEvent.Form.t => unit
ReactEvent.Form module is declared at https://github.com/rescript-lang/rescript-react/blob/v0.10.1/src/ReactEvent.resi#L168
When looking for anything specific to ReScript-React, search that repo.
Looks like you have the correct code to handle the event now. Btw, you have in some places the variant constructor ChangeName and in others ChangeText, I assume the correct one is one of those. The compiler will of course catch this too :-)

Generics in TypedReducer in dart's flutter redux

I'm just playing a bit with flutter, and the generics in function call is confusing me.
Consider the call below:
final signinReducer = combineReducers<SignInState>([
TypedReducer<SignInState,ValidateEmailAction>(_validateEmail),
TypedReducer<SignInState,ValidatePasswordAction>(_validatePassword),
TypedReducer<SignInState,ValidateLoginFields>(_validateLoginFieldsAction),
TypedReducer<SignInState,ChangeLoadingStatusAction>(_changeLoadingStatusAction),
TypedReducer<SignInState,EmailErrorAction>(_emailErrorAction),
TypedReducer<SignInState,PasswordErrorAction>(_passwordErrorAction),
TypedReducer<SignInState,SaveTokenAction>(_saveToken),
TypedReducer<SignInState,ConfirmForgotPasswordAction>(_confirmCodeAction),
TypedReducer<SignInState,CheckTokenAction>(_checkTokenAction),
TypedReducer<SignInState,ClearErrorsAction>(_clearErrorsAction),
TypedReducer<SignInState,ChangeScreenStateAction>(_changeScreenStateAction),
]);
...
SignInState _validateEmail(SignInState state, ValidateEmailAction action){
return state.copyWith(email: action.email);
}
SignInState _validatePassword(SignInState state, ValidatePasswordAction action) =>
state.copyWith(password: action.password);
....
So what does the generic in combineReducers<SignInState> indicate?
Also most confusing is this syntax: TypedReducer<SignInState, ValidateEmailAction>(_validateEmail). What does the second type ValidateEmailAction do here?
in Android Studio Hold the Ctrl and click on TypedReducer or any other types that you don't know, then you can read more info in the source file.
In this Case : TypedReducer
/// Creates a reducer that will only be executed if the dispatched action
/// matches the [Action] type.

Creating custom DOM events with scalajs

I can't find a way to create custom events with scala-js. For instance, with js you can create a custom event like the following (taken from here):
var event = new CustomEvent('build', { 'detail': elem.dataset.time });
However, there is no constructor for CustomerEvent or Event in scala-js that accept arguments. Also, subclassing either such as:
class DrawEvent extends Event {
override def `type` = "draw"
}
leads to
Uncaught TypeError: undefined is not a function
when trying to construct via new DrawEvent()
Any ideas?
To instantiate javascript classes in ScalaJs you have to use js.Dynamic.newInstance:
This should work for your use case:
val event = js.Dynamic.newInstance(js.Dynamic.global.CustomEvent)("build", js.Dynamic.literal(detail = elem.dataset.time)).asInstanceOf[js.dom.CustomEvent]
There is more info available at the remarks portion (all the way at the bottom) of:
http://www.scala-js.org/doc/calling-javascript.html
Here is the same solution using some imports to make it shorter
import js.Dynamic.{ global => g, newInstance => jsnew, literal => lit }
val event = jsnew(g.CustomEvent)("build", lit(detail = elem.dataset.time)).asInstanceOf[js.dom.CustomEvent]
If you want to stay in the typed DOM (assuming you are talking about the scala-js-dom library), you can do:
new CustomEvent().initCustomEvent('build', false, false, elem.dataset.time)
The constructor you are using is actually only specified in DOM 4 (see MDN).