I'm building a Javascript/AJAX heavy web application using jQuery and I'm looking for a way to map URLs/Routes to Javascript functions. I'm using the HTML5 history API and some rewrite rules so all requests will go to one HTML file but idealy what I'd like to do is something along the lines of
Routes.add('/some/path/', 'func_somepath');
Routes.add('/someother/path/', 'func_someotherpath');
function func_somepath(){
alert("You're at somepath");
}
function func_someotherpath(){
alert("You're at someotherpath");
}
Then when someone visited example.com/some/path/ the function 'func_somepath' would be called, similar with /someother/path/. It would also be nice to be able to use Rails-style or regexp variables in the URLs
Routes.add('/items/([a-z]+)', 'func_items');
func_items(id){
alert('You requested '+id+'!');
}
Does anything like this already exist or would I have to write it myself? I don't mind writing it myself but if something already exists there's no point. I'd also like to avoid using 'exec' so how would I go about calling the named functions in Routes.add?
Have you checked out Sinatra's JavaScript counter-part, SammyJS? ...*ba-dum-tish*
Don't use eval unless you absolutely, positively have no other choice.
As has been mentioned, using something like this would be the best way to do it:
window["functionName"](arguments);
That, however, will not work with a namespace'd function:
window["My.Namespace.functionName"](arguments); // fail
This is how you would do that:
window["My"]["Namespace"]["functionName"](arguments); // succeeds
In order to make that easier and provide some flexibility, here is a convenience function:
function executeFunctionByName(functionName, context /*, args */) {
var args = Array.prototype.slice.call(arguments).splice(2);
var namespaces = functionName.split(".");
var func = namespaces.pop();
for(var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
return context[func].apply(this, args);
}
You would call it like so:
executeFunctionByName("My.Namespace.functionName", window, arguments);
Note, you can pass in whatever context you want, so this would do the same as above:
executeFunctionByName("Namespace.functionName", My, arguments);
Hope that helps...
Ember.js, senchatouch2, extjs4 are examples of a framework, that would let you do that easily
Related
I'm fairly new to node.js, prototypical inheritance and the CommonJS module patterns.
Maybe this question was answered a million times, but I couldn't find it, so even a link to the answer is considered an answer.
I have to wrap a module that has both named and unnamed functions, like this:
// a.js
function a(data) {
console.log(data, 'A')
}
function b() {
a('B');
}
module.exports = a;
module.exports.b = b;
Given OOP background I would like to somehow 'inherit' all the functions of the module while I want to override the anonymous function (I'd like to add some fields to the data).
It is very important that after overriding function a in the new module function b should use the overridden method and not the original one.
// 'inherited.js'
var a = require('./a');
function overriddenA(data) {
data.myAddedValue = 'an important addition';
a(data);
}
// I would like to export all other functions and properties of the original module
[magic that overrides the anonymous function while keeping all other functions as they are]
From where I use it should look like this:
var decoratedA = require('./inherited');
decoratedA('stuff'); // it calls overridden function
decoratedA.b(); // it calls the original a.b() which in turn calls the overridden function
Solved our original problem
Check out this: https://stackoverflow.com/a/31459267/2018771 - still if you have any comment on the abstract problem, please answer the question. We are curious :).
I would like to somehow 'inherit' all the functions of the module while I want to override the anonymous function
Wanna use some dark magic? Then __proto__ is the way to go:
var a = require('./a');
function overriddenA(data) {
data.myAddedValue = 'an important addition';
a(data);
}
overriddenA.__proto__ = a;
module.exports = overriddenA;
The cleaner method, without actual inheritance, would be to just copy over all properties from a to overriddenA. You can use Object.assign (or a shim), _.extend, or a simple for in loop for that.
Meanwhile we have solved our original problem which was adding a special header to every calls of request library. In that implementation there were functions like get(), put(), post(), etc. that used one function: function request(...) which was exported module.exports = request
My understanding was that I had to replace that request(...) with our own, adding our header and then calling the original function.
But we were lucky because request(...) returned an object which we could modify according our needs:
Request.prototype.__originalInit = Request.prototype.init;
requestPromise.Request.prototype.init = function(options){
console.log('adding our stuff');
this.__originalInit(options);
};
So this solved the problem for us, but not the original question.
I just want to confirm that I'm not missing something with regards to managing context and overriding methods. I'm using the http-proxy module in a node.js app and I need to override the function HttpProxy.prototype.proxyRequest. I'd like to do it without modifying the original module code directly but haven't been able to find a way to do it.
If I do this:
var httpProxy = require('http-proxy'),
httpProxyOverride = require('./http-proxy-override.js');
httpProxy.HttpProxy.prototype.proxyRequest = httpProxyOverride.proxyRequestOverride;
Then I lose the original context and errors are thrown. If I use apply(), I can provide a new context, but it doesn't appear I can persist the original context.
Based off of this SO thread:
Is it possible to call function.apply without changing the context?
It doesn't appear that there is a way to achieve what I'm trying to do and I'm hoping that someone can confirm this or correct me if I'm wrong.
What about saving the old function and then overwriting it like:
var old = httpProxy.HttpProxy.prototype.proxyRequest;
httpProxy.HttpProxy.prototype.proxyRequest = function () {
old.apply(this, arguments);
//do more stuff
}
taken from Javascript: Extend a Function
Quite a large portion of my work day to day involves working with Dynamics CRM and writing JS to extend the functionality on the forms.
Most clientside interaction in Dynamics involves using an object provided for you when the form loads, which is just Xrm. So you might have something like:
function OnLoad() {
Xrm.Page.getAttribute('name').setValue('Stackoverflow!');
var x = Xrm.Page.getAttribute('name').getValue();
}
I tend to write a wrapper for the Xrm object, mainly because it is a lot easier than remembering some of the chaining and end up with something like:
function WrappedXrm(realXrm) {
var xrm = realXrm;
this.getValue(name) {
return xrm.getAttribute(name).getValue();
}
}
//and then use it as so
var myXrm = new FakeXrm(Xrm);
var myXrmValue = myXrm.getValue('Name');
I am trying out QUnit and wondering how would I go about unit testing in this scenario?
Obviously the example above is a single line, it might not be worth testing it. But assume there was some business logic there that I wanted to test.
The only way I can see is doing some set up before each test along the lines of
var fakeXrm = {};
fakeXrm.Page = {};
fakeXrm.Page.getAttribute = function(name) {
var tempAttr = {};
tempAttr.getValue = function() {
return 'A fake value';
}
}
And then testing on 'A fake value' being returned, but this doesn't 'feel' right to me at all.
Where am I going wrong?
Using Mocks
So in this case, you want to create an instance of WrappedXrm, and pass it an object that mocks the Xrm from your lib ; you need a mock of Xrm.
A first alternative is to write it like you did (which is perfectly valid, if you know what the interface of Xrm is.)
Some libraries like sinon.js or "spies" in the jasmine framework can help you write code like ;
create a 'mock' Xrm, to configure what it should return
create an instance of WrappedXrm with this mock
call the getValue method of WrappedXrm
check that some method was called on the mock
But in the case of javascript, simply created a object that has just the right properties might be okay.
Note that your tests would break if the structure of the "real" Xrm object changes ; that might be what bother's you, but that's always the risk with mocks...
Using the real implementation
If you don't want to test against a mock (which might make sense in case of a wrapper), then maybe you can write the mimimal code that would create an actual Xrm object in your qunit html page (Maybe hardcoding markup ? I don't know the library, so...)
Hoping this helps.
I have been creating my own library for a custom layout script. For ease of use, I am trying to emulate how jQuery exposes its library through the jQuery() which makes the code very easy to read and straightforward. I have come up with something that works but I am not sure if this is the correct way to do this. Rather than keep the functions internal all the functions are "appended" to the library. Anyways, the code which works for me so far is as follows:
slateUI = (function(slateID){
slateUI.ID = slateID;
return slateUI;
});
and a related function looks something like this:
slateUI.doSomething = function(content)
{
//DID SOMETHING USING slateUI.ID
}
I am fairly new to OOP like features of the language. I am sure there is a better way to approach this. The issue that I have is handing down the Element to an appened function call so for instance:
slateUI("#someSlate").doSomething(...)
Obtains its element from the slateUI.ID
Is this the correct way to approach this? Or is this a hacked way that I came up with and there is some straight forward way to do this?
// function which returns a new SlateUI object (so we dont have to use the "new" keyword)
slateUI = function ( slateID ) {
return new SlateUI( slateID );
};
// class definition
function SlateUI ( slateId ) {
this.id = slateId;
}
// methods added to the class prototype (allows for prototypical inheritance)
SlateUI.prototype.someFunction = function() {
alert( this.id );
return this; // adding this line to the end of each method allows for method chaining
};
// usage
slateUI( 'someid' ).someFunction();
The short version of your question is that you're looking for the ability to chain your functions.
This is achieved simply by returning the relevant object from each function. If the function has no other return value, then just return the this variable, to pass control back to the caller.
I am trying to write a javascript class that loads script files as they are needed. I have most of this working. It is possible to use the library with the following Syntax:
var scriptResource = new ScriptResource('location/of/my/script.js');
scriptResource.call('methodName', arg1, arg2);
I would like to add some additional syntactic sugar so you could write
var scriptResource = new ScriptResource('location/of/my/script.js');
scriptResource.methodName(arg1, arg2);
I'm almost certain that this isnt possible but there may be an inventive solution. I guess what there need to be is some sort of methodCall event. SO the following could work
ScriptResource = function(scriptLocation)
{
this.onMethodCall = function(methodName)
{
this.call(arguments);
}
}
This code is obviously very incomplete but I hope it gives an idea of what I am trying to do
Is something like this even remotely possible?
There is a non standard method, __noSuchMethod__ in Firefox that does what you're looking for
have a look at
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/noSuchMethod
so you could define
obj.__noSuchMethod__ = function( id, args ) {
this[id].apply( this, args );
}
If the set of method names is limited, then you could generate those methods:
var methods = ["foo", "bar", "baz"];
for (var i=0; i<methods.length; i++) {
var method_name = methods[i];
WildCardMethodHandler[method_name] = function () {
this.handleAllMethods(method_name);
};
}
edit: Posted this answer before the question changed dramatically.
An intermediary solution might be to have syntax such as:
var extObj = ScriptResource('location/of/my/script.js');
extObj('methodname')(arg1,arg2);
the code might look like this:
function ScriptResource(file) {
return function(method) {
loadExternalScript(file);
return window[method];
}
}
All kinds of assumptions in the code above, which I'd let you figure out yourself. The most interesting, IMHO, is - in your original implementation - how do you get the proxyied method to run synchronously and return a value? AFAIK you can only load external scripts asynchronously and handle them with an "onload" callback.