Can I override/extend Meteor methods? - meteor

Is it possible to somehow override a method in Meteor?
Or define another function such that both will get called?
In my regular code:
Meteor.methods(
foo: (parameters) ->
bar(parameters)
)
Somewhere else that gets loaded later (e.g. in tests):
Meteor.methods(
# override
foo: (parameters) ->
differentBehavior(parameters)
# I could call some super() here
)
So I would expect to either have both bar and differentBehavior executed or only differentBehavior and some possibility to call super().
Does this exist?

To override a method, on server side you can do:
Meteor.methods({
'method_name': function () {
//old method definition
}
});
Meteor.default_server.method_handlers['method_name'] = function (args) {
//put your new code here
};
The Meteor.default_server.method_handlers['method_name'] has to be included after the method definition.
To override a method (also know as a stub), on client side you can do:
Meteor.connection._methodHandlers['method_name'] = function (args) {
//put your new code here
};
The Meteor.connection._methodHandlers['method_name'] has to be included after the method definition.

There are lots of ways you can do what you are intending to do.
For instance, the simplest way to overwrite any function would be to do something like:
Meteor.publish = function() { /* My custom function code */ };
We just over-wrote the Meteor.publish with our own instance.
However, if you want to wrapper a function like a proxy (I believe this is called a "proxy pattern":
var oldPublish = Meteor.publish();
Meteor.publish = function() {
oldPublish(arguments); // Call old JS with arguments passed in
}
ES6 also added a Proxy object that allows you to do some similar things (read about it here).
Also there are lots of AOP libraries (CujoJS, jQuery-AOP, and node-aop to name a few) for JavaScript that allow you to do before, after, around pointcuts on functions/objects. You could even roll-your-own if you wanted too.

Related

Call method .NET from JavaScript

I have a method in .NET (GetDataStationParts), which I declare with 2 parameters, I want to call it from a JavaScript, and I use the InvokeMethodAsyn function in this way:
const { data } = require("jquery");
function GetParteScrap()
{
var idestacionjs = document.getElementById('getestacion');
var idmodelojs = document.getElementById('getmodelo');
var tablascrap = DotNet.InvokeMethodAsyn("YMMScrapSystem", "GetDataStationParts", idestacionjs, idmodelojs);
console.log(tablascrap);
}
To do it, I base it on an example on the web but I'm not sure where it gets the DotNet object to then invoke the method, the intention of my code is that after selecting parameters of 2 , go to the database and execute a SQL-level function, which will return a table, with the function GetDataStationParts, I try to give it the functionality to execute my method at the DB level as follows
[JSInvokable]
public async Task<IEnumerable<GetEstacionParte>>GetDataStationParts(int modelo, int estacion)
{
var resul = await _context.Set<GetEstacionParte>().FromSqlInterpolated($"SELECT * FROM dbo.GetEstacionParte({modelo},{estacion})").ToArrayAsync();
return resul;
}
The SQL level function works correctly, but when running the application at the console level in the browser, it throws the following error, where it indicates that the function is not defined
Where could the error be? Thank you for reading
require() is not a feature that is built into the browser. Javascript environment does not understand how to handle require(), In Node.js by Default this function is available.
I suspect you most probably missing some reference here. You can either download require.js from here & link with your application or use below script tag.
<script src="https://requirejs.org/docs/release/2.3.5/minified/require.js"></script>

Javascript class attributes loaded async in constructor?

I'm struggling with JavaScript async patterns to achieve this :
I have a class (I'm using CoffeeScript) with some attributes initialized in the constructor from some async calls. Then I have some methods that require these attributes to work. Here is a simplified example of what I'm trying to do :
# Class definition
class window.MyClass
constructor: ->
#attr = ... # loaded with an ajax call or whatever
myMethod: ->
console.log #attr
# User code
c = new MyClass()
c.myMethod() # should console.log the value loaded asynchronously
So the issue will be that when myMethod() is called, the async call hasn't finished yet.
I know a few solutions, however they imply moving the method call inside a callback (or a then function with promises). I want to avoid this to be able to call this method from click handlers or something else totally unrelated.
Also note that I can't move the async call inside my method since I will probably have several methods using the attribute, and I don't want to load the attr at each call, but only in the constructor.
Any idea ?
I finally found a way to do this. Not sure if it's very clean, but it works and fits my needs.
After loading asynchronously my attr value, I dispatch an event MyClassReady.
In my constructor, I've added a first listener to MyClassReady that sets an attribute ready to true.
Then, in myMethod, I wrapped my code in a function. Then I call this function if ready is true, otherwise I bind this function to the MyClassReady event.
The result looks like this :
# Class definition
class window.MyClass
constructor: ->
# Async load of `attr`
self = this
loadAttr (val) ->
self.attr = val
window.dispatchEvent new Event 'MyClassReady'
window.addEventListener 'MyClassReady', ->
self.ready = true
myMethod: ->
self = this
callback = ->
console.log self.attr
# If the attrs are already loaded
if #ready
callback()
else
window.addEventListener 'MyClassReady', ->
callback()
# User code
c = new MyClass()
c.myMethod() # this will wait until attr is loaded
I think it would be nice to move this code to a library, however with all the self = this stuff it seems complicated.
Edit: note that custom events aren't supported by IE...

using export in alloy controller versus attaching functions directly to the '$' scope

here is the code of an alloy controller written in two different ways. Although the both work the same, Which one might be best practice?
example 1 of controller.js:
var currentState = true;
$.getState = function(){
return currentState;
}
example 2 of controller.js:
var currentState = true;
exports.getState = function(){
return currentState;
}
Titanium is based on the CommonJS framework. The exports variable is a special variable used typically to expose a public API in a class object. So when you want to expose a method of doSomething() on the MyModule.js class you would use the exports variable like this:
exports.doSomething() = function(args) {
//Some really cool method here
};
Then reference that class using
var myModule = require('MyModule');
myModule.doSomething();
However when referencing a view object the typical way to reference the is using the $. shortcut. You can see they prefer that method in the official documentation.
http://docs.appcelerator.com/platform/latest/#!/guide/Alloy_XML_Markup
The $ variable holds a reference to your controller instance. It also contains some references to all indexed views (understand, views for which you supplied an index in you xml markup).
Both ways are strictly equivalent as, during the compilation, Alloy will merge the content of the exports with your controller referenced in $. Adding them directly to the instance won't change a thing.
Neverthless, developers are used to see the public API as the set of functions exported via the special variable exports; Thus, I will recommend to keep using it in a clean and clear way (for instance, defining your functions in your module scope, and only expose them at the end or beginning of your controller).
function myFunction1 () { }
function myFunction2 () { }
function myFunction3 () { }
exports.myFunction1 = myFunction1;
exports.myFunction3 = myFunction3;
Thereby, your API is quite clear for people diving into your source code. (A readMe file is also highly recommended :) ).

How to reference an anonymous JavaScript function?

I'm trying to call a Page Method using a jQuery 'attached' event function, in which I like to use the closure to keep the event target local, as below, but page method calls declare several 'error' functions, and I would like to use one function for all of them. If, in the below code, I was handling an error and not success, how could I use my single, anonymous handler for all 3 error functions?
$(":button").click(function () {
var button = this;
PageMethods.DoIt(
function (a, b, c) {
alert(button);
});
});
This example passes an anonymous function for the success callback. There is only one of these. If I was passing an error callback, how could I use 'function (e, c, t)' for all 3 error callbacks?
ADDED: What I would like to do here is trigger an AJAX call whenever the user clicks a toggle button (checkbox), but to improve responsiveness, I want to toggle the button state immediately, and only 'untoggle' it if the AJAX call fails.
Now, in my client-side click() event handler, I would like to use anonymous functions inside the scope of click()' so that the functions have access to thethisevent argument, but I don't want to 'declare' three functions for theonTimeout,onError, and 'onAbort arguments of the PageMethods.MyFunction function. if I declare a named function outside of the click handler, it no longer has access to the 'this' parameter of the click() event handler.
If your goal is to keep this function out of global scope, use the module pattern:
(function() {
function asplode() {
alert('Your head asplode.');
}
$('body').click(asplode);
})();
I think you can put a variable with name in front of it, like this:
var myFunction = function(a, b, c) { ...
It's been a while I haven't done this but you could give it a try.
You have to assign an anonymous function to a variable using var (always use var, otherwise a variable gets global scope, which may cause unexpected results (e.g., never declare variable i globally)). That's the only way to reference it:
var myFunction = function (a, b, c) {
/* tum de dum */
}; // don't forget this semicolon
Then you can use this function in different places:
$(":button").click(myFunction);
/* don't put braces after the function name when referencing it,
else it will be called immediately */
You can find more information about function expressions and function declarations in the article Named function expressions demystified.
You can't. The whole point of an anonymous function is that it has no name and thus cannot be referenced. (In fact, "anonymous" is basically the Greek word for "unnamed".)
If you want to reference it, you need to give it a name.
From inside the anonymous function, you can reference it as arguments.callee (this is how anonymous recursion is achieved).
If I understand correctly what you want to do, you may be able to accomplish it like this:
function handler(a, b, c) {
alert(this); // button
}
$(":button").click(function () {
var button = this;
PageMethods.DoIt(function () {
handler.call(button, a, b, c);
});
});

ASP.Net ScriptControl - Add the Javascript get_events method : Possible?

So I've run into a snag, apparently the get_events method is only "included" with the ExtenderControl class.
What I need to do:
Be able to call the get_events Javascript method using a ScriptControl since using an ExtenderControl isn't really possible at this point.
I am hoping there is an easy way to have the scriptControl's javascript object inherit from something (If that's even possible).
Turns out the get_events method is really simple to create. You just need a field to hold a dictionary, a couple lines of code, and something to call the event if needed:
getEvents: function()
{
if (this._events == null)
{
this._events = new Sys.EventHandlerList();
}
return this._events;
},
And now for access:
onItemSelected: function(args)
{
this.raiseEvent('userItemSelected', args);
},
raiseEvent: function(eventName, eventArgs)
{
var handler = this.getEvents().getHandler(eventName);
if(handler)
{
handler(this._autoComplete, eventArgs);
}
},
Basically events is just a dictionary that holds the name of the event and the reference to the method to call. Once you have the method (handler), it's just a matter of calling it.

Resources