Provide callback for custom component - dart

I made a custom component which basically wraps a d3 line chart. Now I want to be able to register a callback for clicks on the lines in the chart.
I gave the component a #NgCallback parameter, which I then send events to:
class NetworkSummaryComponent implements NgShadowRootAware {
#NgCallback('callback')
Function callback;
void onShadowRoot(ShadowRoot shadowRoot) {
...
chart.callMethod('listen', ['line-click', (ev) {
var name = ev.callMethod('getLineName');
print(name);
callback({'name': name});
}]);
}
}
When using the component, I specify a function of my controller as callback:
<network-summary
...
callback="ctrl.lineClicked">
</network-summary>
However, that function is never actually called, put I know the callback arrives from the JS side because the print in the first snippet is executed.
If I instead specify the attribute as callback="ctrl.lineClicked()" I get a strange exception:
Closure call with mismatched arguments: function 'call'
I could not find any official documentation on how to properly do callbacks, so I'm not exactly sure what I'm doing wrong.. Any ideas?

It turns out that I had to explicitly name the expected arguments in the attributes:
<network-summary
...
callback="ctrl.lineClicked(name)">
</network-summary>
Hope this is useful to the next person having this problem.

Related

programatically adding an on-tap attribute referencing a dart function for a HtmlElement

I have a dart function:
_addSelection(HtmlElement ele){
ele.classes.add("selection");
}
I would either want 1 or 2 things to occur, either A) execute an on-tap and on-track function given the selection class.... OR Dynamically add the on-tap and on-track attributes referencing reflected dart functions.
I have 2 functions:
#reflectable
onTap(CustomEventWrapper cew, params){
//...
}
#reflectable
onTrack(CustomEventWrapper cew, params){
//...
}
I was looking at the HtmlElement class and documentation and I wasnt quite understanding how to do this.
Edit if I were using jQuery and Javascript, I would be doing something as simple as:
$(document).on("tap", function(){});
$(document).on("track", function(){});
Edit2 Added Angular Dart because both designs leverage Dart backend and markup front end.
You could do:
_addSelection(HtmlElement ele) {
ele.classes.add("selection");
ele.onTouchEnd.listen((TouchEvent touch) {
...
});
}
That would give you something close to the tap event. If you wanted to get really fancy you could also listen for onTouchStart and only call your onTap handler when the time between the start and end is small.

iron-ajax on-response doesnt recognize dart reflected method

My ajax is defined as:
<iron-ajax id="myAjaxId" auto
url="http://localhost:8088/test_server/v1/users/35"
handle-as="json"
on-response="{{handleResponse}}" ></iron-ajax>
and in my dart i say:
#reflectable
void handleResponse ( e, Map data ){
print("hand response fired");
f_name = data["f_name"];
l_name = data["l_name"];
id = data["id"];
}
not only does it not fire the print statement, but in the Chromium console, when it is run, it says:
[my-ajax-fetcher::_createEventHandler]: listener method `{{handleResponse}}` not defined
I was looking up some other examples and noticed #reflectable is the tag i should be applying.
I was also trying to look up what the target signature needs to look like, and didnt see anything.
You don't need {{}} for event handlers in Polymer 1.x just on-response="handleResponse"

Silverstripe 3: removeByName not working

Good morning,
I've been trying to use the removeByName method and it doesn't work.
I'm basically trying to hide a field in my DataObject within the forms that's generated by ModelAdmin, which manages the object.
See sample code below:
///DataObject snippet...
class MyObject extends DataObject{
public static $db = array(
'Title' => 'Varchar',
'Desc' => 'Text',
'Template' => 'HTMLText',
);
//#Override
public function getCMSField(){
$fields = parent::getCMSField();
$fields->removeByName('Template'); /// DOESN'T WORK!!!
return $fields;
}
}//class
Note: I'm not getting any errors. I'm just still seeing the field on the forms (Add and Edit) as usual.
Any help appreciated, thanks.
Okay, I found the issue.
I was just going over the API again for the millionth time, and recognized that I've named the function wrong. See correction below:
///Correction, forgot to add the 's' at the end of both the function and the parent call.
public function getCMSFields(){
$fields = parent::getCMSFields();
}
I can understand an error not being generated in Apache logs for the function because it's legit. But as for the parent call, it should of generated an error since the method don't exists. (Theory: Perhaps, since the function was never actually being called, the parent call wasn't being executed and thus no errors [run-time error]).

Getting the parameters of a method call from a clang match callback

I'm adapting the Clang tool-template (as described here) to search for a particular method call in my code. In order to later rewrite that call, I would like to get the type of the parameters the method was called with, as well as the type of the object the method was called on.
I managed to find a matcher that calls back the following:
class AddListenerPrinter : public MatchFinder::MatchCallback
{
public :
virtual void run(const MatchFinder::MatchResult &Result) {
if (const auto *FS = Result.Nodes.getNodeAs<clang::MemberExpr>("ListeningBound"))
{
FS->dump();
}
}
};
which prints out:
MemberExpr 0x7fb05b07b948 '<bound member function type>' .addListener 0x7fb05b077670
`-MemberExpr 0x7fb05b07b918 'class MyCore' lvalue ->mCore 0x7fb05b078e30
`-CXXThisExpr 0x7fb05b07b900 'class MyComponent *' this
Now I can't find any way to retrieve the type of the object the method was called on (here class MyCore) or the type of the method argument (here class MyComponent).
How can I do this?
I found the answer by browsing the code of the existing matchers.
Using matcher = memberCallExpr( callee(methodDecl(hasName("addListener"))) )
I was able to retrieve a CXXMemberCallExpr node. Then getting the type of the object the method was called on:
// FS is the CXXMemberCallExpr
// Prints out the type of x in x.method()
llvm::outs() << FS->getRecordDecl()->getName();
and the method parameters are accessible through FS->getArg(n).
Bottom line is: Find the CXX object that contains what you're looking for first (e.g. which class has methods to access function arguments?), then find the matcher that will return the same type of object in ASTMatchers.h.
Hoping this can help anybody else with the same problem.

Return response object in event listener not working when triggered in controller plugin

I implemented a shared event listener that manipulates and returns the response object with an error template showing the message of the triggered error code. (I'm not talking about throwing exceptions and catching them in a dispatch.error listener!)
This works fine when I call this event in a controller action. However, when I trigger my error event in a controller plugin that is called in the onDispatch method of the controller, only the status code is set correctly. But the called action is fully executed and no error page is shown.
I have absolutely no idea why this happens and I hope, someone is able to explain me the dispatch/event triggering/short circuiting/returning response issue here.
Following extracts might give you an impression of my code:
Listener:
class SharedErrorListener implements SharedListenerAggregateInterface {
...
public myErrorFunction(EventInterface $e) {
// get error code
// set status code to injected response object
// add error template to injected view model
// return response
}
}
Random controller action (works fine):
return $this->getEventManager()->trigger('error', $this, array(
'errorCode' => my_error_code
));
onDispatch() of controller:
// call plugin, if return value given return it (response must be returned?!).
$r= $this->plugin('myplugin')->doIt();
if (isset($r)) {
return $r;
}
class myplugin doIt() where error is triggered, but error template not showing up:
return $this->getController()->getEventManager()->trigger('error', $this, array(
'errorCode' => my_error_code
));
As the code in the controller and the controller plugin ist pretty much the same, I think it must depend on some application state. I did a lot of research, but couldn't find, what the problem might be. But as the event is triggered correctly and also the right status code is set to the response, I am just very confused. I don't want to implement an ErrorController (which would allow to call a redirect), because I think the solution via EventManager is actually very nice.
I'm too busy to actually read all the above, but from what my impression is, this code-snipped may actually help you out:
$trigger = $this->getEventManager()->trigger(self::EVENT_IDENTITY_GET, $identity);
if ($trigger instanceof ResponseCollection && !is_null($trigger->last())) {
return $trigger->last();
}
I finally found the problem here. By returning the response during the onDispatch process, the onDispatch() of the AbstractActionController wasn't called. In that function the return value of the controller action, e.g. the view model, is set as "result" of the MvcEvent. I just had to set the template that was set in the listener as the result for the event:
$r = $this->plugin('my_plugin')->doIt();
if ($r instanceof ResponseCollection) {
$e->setResult($this->getServiceLocator()->get('view_manager')->getViewModel()->getChildren());
return $r;
}
Hope this helps someone.

Resources