Underscore: _.wrap doesn't support wrapping function with argument

Created on 9 Mar 2013  ·  8Comments  ·  Source: jashkenas/underscore

Today while writing code using underscore and backbone i had to wrap some functions. I saw following example on underscorejs.org

var hello = function(name) { return "hello: " + name; };
hello = _.wrap(hello, function(func) {
return "before, " + func("moe") + ", after";
});
hello();
=> 'before, hello: moe, after'

on the second last line
what if the function call is like
hello("umar");
I means to say that arguments are coming from outside.

question

All 8 comments

Wrap already takes care of most of this for you. The source for wrap is pretty short to read through. That or you can take a gander at the extended example below:

var greet = function(name, language){
  var response
  if (language === "sp") {
    response = "Hola"
  } else if (language === "fr") {
    response = "Bonjour"
  } else {
    response = "Hello"
  }
  return response + " " + name
}
greet("Ted", "fr"); // => "Bonjour Ted"
greet = _.wrap(greet, function(old_greet, lang){ return old_greet("Ted", lang); } );
greet("sp"); // => "Hola Ted"

Thanks for this quick response. It was very much helpful.
I am using backbone to develop an enterprise app.
view.js
var view = Backbone.View.extend({

authorizeCreateAction: function (){
//here "this" points to view
this.createAlert: _.wrap(this.createAlert, function(_createAlert, _type){
//authorize create action
return _createAlert(_type);
});
},
createAlert: function(type){
//PROBLEM:
// Here "this" points to [window global]
}
});
see inside createAlert function when I was calling createAlert function directally it was pointing to view but when I wrote wrapper function it started pointing to [window global]
I want to change referance of this to be pointing to "view"

I am new to underscore, please ignore if question is irrelevant.
BTW underscore is awesome

You'll need to call _createAlert with a context like below. Hope that helps. :)

return _createAlert.call(this, _type);

it seems underscore _wrap only supports one parameter , use this instead:

fn = (function(fn,before,after, self) {
return function() {
if(before) before.apply(self,arguments);
var res = fn.apply(self,arguments);
if(after) after.apply(self,arguments);
return res;
}
})(fn, before, after, this )

You can also use partial for that zarehb

tnx megawac, partial is more for pre-filling the arguments not calling a before and after function

Wrap is implemented via _.partial fyi

fn = _.partial(function(fn, before, after, self) {
    var args = _.rest(arguments, 4);
    if (before) before.apply(self,args);
    var res = fn.apply(self,args);
    if (after) after.apply(self,args);
    return res;
})(fn, before, after, this )

that's correct and it will work, but in case anyone wants a pure js solution can take mine specially that using underscore doesn't give you any benefit in this case!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

arypbatista picture arypbatista  ·  3Comments

danilopolani picture danilopolani  ·  5Comments

Francefire picture Francefire  ·  5Comments

jdalton picture jdalton  ·  6Comments

dmaicher picture dmaicher  ·  9Comments