I just started with node.js and express.js. As server-side templating framework I picked Hogan.js. I am now trying to find out how I can do i18n with Hogan.js, and I found some information in this post. It seems that you always have to pass in the i18n function together with the context of the view. Is it possible to configure this or set this up at a single place in the application? It seems very cumbersome if I have to do this for each and every view separately. Thanks!
You could take a look at Express-lingua which seems to perfectly match your needs.
wrap the render function of hogan if you must
var origional = Hogan.template.prototype.render;
Hogan.template.prototype.render = function (context, partials, indent) {
context['i18n'] = function () {
return function () {
return 'i18n';
};
};
return origional.call(this, context, partials, indent);
};
Related
Mainly out of curiosity, but also for a better understanding of Meteor security, what is the reason(ing) behind Meteor.user() not working inside publish functions?
The reason is in this piece of code (from meteor source code)
Meteor.user = function () {
var userId = Meteor.userId();
if (!userId)
return null;
return Meteor.users.findOne(userId);
};
Meteor.userId = function () {
// This function only works if called inside a method. In theory, it
// could also be called from publish statements, since they also
// have a userId associated with them. However, given that publish
// functions aren't reactive, using any of the infomation from
// Meteor.user() in a publish function will always use the value
// from when the function first runs. This is likely not what the
// user expects. The way to make this work in a publish is to do
// Meteor.find(this.userId()).observe and recompute when the user
// record changes.
var currentInvocation = DDP._CurrentInvocation.get();
if (!currentInvocation)
throw new Error("Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.");
return currentInvocation.userId;
};
Is there a best-practice solution to be able to use within in promise this? In jQuery i can bind my object to use it in my promise/callback - but in angularJS? Are there best-practice solutions? The way "var service = this;" i don't prefer ...
app.service('exampleService', ['Restangular', function(Restangular) {
this._myVariable = null;
this.myFunction = function() {
Restangular.one('me').get().then(function(response) {
this._myVariable = true; // undefined
});
}
}];
Are there solutions for this issue? How i can gain access to members or methods from my service within the promise?
Thank you in advance.
The generic issue of dynamic this in a callback is explained in this answer which is very good - I'm not going to repeat what Felix said. I'm going to discuss promise specific solutions instead:
Promises are specified under the Promises/A+ specification which allows promise libraries to consume eachother's promises seamlessly. Angular $q promises honor that specification and therefor and Angular promise must by definition execute the .then callbacks as functions - that is without setting this. In strict mode doing promise.then(fn) will always evaluate this to undefined inside fn (and to window in non-strict mode).
The reasoning is that ES6 is across the corner and solves these problems more elegantly.
So, what are your options?
Some promise libraries provide a .bind method (Bluebird for example), you can use these promises inside Angular and swap out $q.
ES6, CoffeeScript, TypeScript and AtScript all include a => operator which binds this.
You can use the ES5 solution using .bind
You can use one of the hacks in the aforementioned answer by Felix.
Here are these examples:
Adding bind - aka Promise#bind
Assuming you've followed the above question and answer you should be able to do:
Restangular.one('me').get().bind(this).then(function(response) {
this._myVariable = true; // this is correct
});
Using an arrow function
Restangular.one('me').get().then(response => {
this._myVariable = true; // this is correct
});
Using .bind
Restangular.one('me').get().then(function(response) {
this._myVariable = true; // this is correct
}.bind(this));
Using a pre ES5 'hack'
var that = this;
Restangular.one('me').get().then(function(response) {
that._myVariable = true; // this is correct
});
Of course, there is a bigger issue
Your current design does not contain any way to _know when _myVariable is available. You'd have to poll it or rely on internal state ordering. I believe you can do better and have a design where you always execute code when the variable is available:
app.service('exampleService', ['Restangular', function(Restangular) {
this._myVariable =Restangular.one('me');
}];
Then you can use _myVariable via this._myVariable.then(function(value){. This might seem tedious but if you use $q.all you can easily do this with several values and this is completely safe in terms of synchronization of state.
If you want to lazy load it and not call it the first time (that is, only when myFunction is called) - I totally get that. You can use a getter and do:
app.service('exampleService', ['Restangular', function(Restangular) {
this.__hidden = null;
Object.defineProperty(this,"_myVariable", {
get: function(){
return this.__hidden || (this.__hidden = Restangular.one('me'));
}
});
}];
Now, it will be lazy loaded only when you access it for the first time.
Is there a way (preferably Firefox or Chrome) to log all the DOM methods invoked/properties modified by a Web app?
I need this to understand some of the working of web apps whose code I don't have in non-minified version.
I understand that this won't give me the complete picture, but I am more interested in the web app's interaction with the browser for my purpose.
You can log all method calls for specific class of objects by wrapping all of its methods with a custom logging function:
var originalMethod = SomeObject.prototype.someMethod;
SomeObject.prototype.someMethod = function() {
//log this call
originalMethod.apply(this, arguments);
}
I've created a function that hooks up such wrappers to all (non-inherited) methods of given class and logs all calls to the console:
function logMethodCalls(className) {
function wrapMethod(className, methodName, prototype) {
var orgMethod = prototype[methodName];
return function() {
window.console.debug('%c'+className+'::%c'+methodName, 'color: #FBB117; font-weight: bold', 'color: #6F4E37', {
details: {
scope: this,
arguments: arguments
}
});
return orgMethod.apply(this, arguments);
};
}
if(!window[className] || typeof window[className] !== 'function') {
window.console.error('Invalid class name.');
return;
}
var prototype = window[className].prototype;
for(var i in prototype) {
if(prototype.hasOwnProperty(i)) {
if(typeof prototype[i] === "function") {
prototype[i] = wrapMethod(className, i, prototype);
}
}
}
}
I'm running it like this:
["Document", "DocumentFragment", "Element", "Event", "HTMLElement", "HTMLDocument", "Node", "NodeList", "Window"].forEach(function(i){
logMethodCalls(i);
});
You can customise the array above to track only classes that you are interested in.
The output looks like this:
To be perfectly honest there is so much output that I don't think this type of debugging may be usable. You can try extending this solution even more by observing all properties (e.g. by defining getters and setters or proxies for all objects), but this will get even more messy.
Great idea! Tracking DOM changes may be useful when trying to understand how website/app works, but also while searching for performance bottlenecks (DOM access is expensive).
I haven't found extension that does exactly what you are asking for, so I've created one. You can install DOMListener from Chrome Web Store.
DOMListener extension uses MutationObserver to catch all DOM changes and outputs friendly messages to the DevTools console. Note that I'm using console.debug() so you can easily filter these messages out:
Code is available on GitHub. If you prefer to avoid installing the extension or you want to get a similar output in Firefox, simply grab the DOMListener.js file and run it in the console.
I'm trying to setup an MVC architecture for Express. What I am trying to accomplish is a routing mechanism close to ASP.NET's. For example for the following route:
/users/detail/1
express should call a module under controllers directory named users.js. Within the users.js module is a function named detail. And within the function, I can simply get the request parameter to get the id of the user.
My idea is to extract the users and map it to a users.js file using a simple require statement. But how can I tell express to call details() function by simply extracting the action part of the route which is 'detail' in the above example. I can use eval() but I am hearing that it's not a safe thing to do? Thanks in advance.
In browser-side javascript, you can typically do the following
function a () { console.log('called a');
window['a'](); // called a
You can do similar in node by replacing window with global such as
function a () { console.log('called a');
global['a'](); // called a
However, if you are pulling this function in from another file, it will be little different. Let's assume that you have the following file a_module.js:
exports.a = function () { console.log('a called'); }
And then in you're main file, you can do the following:
var a_mod = require('./a_module.js');
a_mod['a'](); // a called
I'd like to call a simple YUI3 function from within a JavaScript function.
Here is some code that does what I want in a very verbose way:
function changeContent (message) {
YUI().use("node", function(Y) {
Y.all('#content-div').setContent(message);
});
}
Is there a better way to do this?
NOTE: I don't want to attach this function to any event, I just want a global changeContent() function available.
If you want the API to exist outside of the YUI().use(...function (Y) { /* sandbox */ }), you can capture the returned instance from YUI().
(function () { // to prevent extra global, we wrap in a function
var Y = YUI().use('node');
function changeContent(message) {
Y.one('#content-div').setContent(message);
}
...
})();
Be aware that there is a race condition here if you use the seed file (yui-min.js) and dynamic loader to pull in the other modules. changeContent could be called before the Node API is loaded and added to Y. You can avoid this by using a combo script up front. You can get the combo script url from the YUI 3 Configurator. There is a performance penalty for loading the modules in a blocking manner up front. You may or may not notice this in your application.
You can do like this:
(function(){
YUI().use("node", function(Y) {
APP = {
changeContent: function(message){
Y.all('.content-div').setContent(message);
}
};
});
})();
Then, you can call changeContent by calling APP.changeContent(message); from anywhere you want. Hope this helps. :D