Mongoose promise in user provider object with prototype functions

Sorry i couldn't come up with a straight forward question/title, but here's the thing. I have the following construct:

var userProvider=function(login){
   this.getUser=mongoose.find(login).exec();
}
userProvider.prototype.doStuffWithUserData=function(){
   this.getUser.then(function(user){
       ...
   });
} 
userProvider.prototype.doOtherStuffWithUserData=function(){
   this.getUser.then(function(user){
       ...
   });
} 

Is there a a nicer way, such that i don't need to call the promise in every prototype function, though the prototype functions being evaluated only until the data is there?

Here is how you can do it with decoration. This is tricky because the promise is not available when you create the function yet:

function whenReady(fnToRun){
    return function runsWhenReady(){ // the decorated function
        // keep track of arguments
        var args = Array(arguments.length + 1); // inline slice is much faster
        for(var i = 0; i < arguments[i]; i++) args[i+1] = arguments[i];
        return this.getUser.then(function(user){
            args[0] = user;
            return fnToRun.call(this, args); // append user and call with args
        }.bind(this)); // maintain context)
    };
}

This would let you do:

userProvider.prototype.doStuffWithUserData = whenReady(function(user){
    // user is available here 
});

myUserProviderInstance.doStuffWithData(); // inside the call user is available

userProvider.prototype.otherStuff = whenReady(function(user, x){
    // user is available here 
});

myUserProvider.otherStuff(15); // x will be 15 and user will be available, promise returned

This approach can be generalized to a more general whenReady that takes a "waitFor" argument. It's also worth mentioning that if you use a library like Bluebird it already ships with bind and method which let you do this in a more easy way.

Is there a a nicer way, such that the prototype functions being evaluated only when the data is there?

I'd recommend not to execute the find sideeffect in the constructor and create the promise there, but get the result of the mongoose.find(login).exec() passed into the constructor, as laid out in Is it bad practice to have a constructor function return a Promise?

I'd go with the bad practice case

To avoid the repetition, you can create your prototype methods like this:

function userProviderMethod(n, m) {
    UserProvider.prototype[n] = function() {
        var args = Array.prototype.slice.call(arguments),
            that = this;
        return this.getUser.then(function(user) {
            args.unshift(user);
            return m.apply(that, args);
        });
    };
}

function UserProvider(login){
    this.getUser = mongoose.find(login).exec();
}
userProviderMethod("doStuffWithUserData", function(user /*, … */) {
    // …
});
userProviderMethod("doOtherStuffWithUserData", function(user) {
    // …
});

Notice that none of these "methods" will actually ever get executed when .getUser did get rejected.