3

I have some kind of error concept regarding to the creation of functions into functions, I would appreciate any help in here.

Let's say I have to apply the jquery $.post function several times, so I dont want to repeat myself, so I create something like this.

 myLoadFunction(url, function) {

     $.post(url, function( data ) {
        //something generic
     })
     .done(function(data) {
       //what I want to put on my caller function
     })
     .fail(function(data) {

       //something generic
     });

 }

so I can execute it like this:

myLoadFunction("myurlblabla", function() {
       //everything I need into the .done
});

Any ideas? I am not even sure if this is possible, so pls do not kill me :)

Regards!

3
  • Have you tried running the code? What errors are you getting? Commented May 19, 2014 at 14:27
  • Where are you going to fire the callback function you passed in? You want to rename the parameter function to something less reserved. And to call it -- .done(myFunc) will work Commented May 19, 2014 at 14:29
  • It's not clear if you have some custom code you want to run before the callback or not. Commented May 19, 2014 at 14:33

4 Answers 4

4

The structure you're trying to achieve is already there for you:

You want:

myLoadFunction("myurlblabla", function() {..if success...});

But You already have it in:

myLoadFunction("myurlblabla").done(...)  // nicer right ?

Using the deferred object, it already provides this:

Change the structure to return a deferred obj: ( or better see my edit)

myLoadFunction(url) 
{
    return $.post(url, function(data) {
        //something generic
    });
}

var R = myLoadFunction("myurlblabla");

R.done(function (){ do whatever}); // here is your actual question.
R.fail(function (){ do whatever});

Also don't mix responsibilites !

myLoadFunction should do load nothing more.

With the result of the load you can do other thing outside of this load factory function.

don't put logic there

edit

Regarding your comment :

but on this, would I allow to preserve the same answers for fail and the generic load? I just dont want to repeat the fail case nor the case when data is empty

You could set a function ( one time) which you will reference each time : ( don't put this on global scope. an object which contains these function would be great).

function myGENERICCallback(){ something I don't want to repeat}
function mydoneCallback(){ something I don't want to repeat}
function myfailCallback(){ something I don't want to repeat}
function myAlwaysCallback(){ something I don't want to repeat}

Now - you can do this :

var R = myLoadFunction("myurlblabla");

R.done(mydoneCallback); 
R.fail(myfailCallback);

And so your load function would look like :

myLoadFunction(url) 
{
    return $.post(url, myGENERICCallback); 
}
  • myGENERICCallback would always be called
  • you load function does not contain any logic
  • you can have specific callbacks for each case
  • you keep single responsibility principle.
  • you don't repeat your code
  • you only need to change in one place
  • Other can subscribe to your deferred also.
Sign up to request clarification or add additional context in comments.

7 Comments

This solution would allow to specify different callbacks for each. Is more flexible.
but on this, would I allow to preserve the same answers for fail and the generic load? I just dont want to repeat the fail case nor the case when data is empty
@andresmijares25 What do you mean "repeat the fail case nor the case when data is empty"?
@andresmijares25 So write them outside ( only 1 time) like var myCbFunc = function (){...}; R.done(myCbFunc);
I mean, "something generic" won't vary, that is what I dont want to repeat
|
3

You aren't far off, you just need to call the function you pass in:

myLoadFunction(url, callback) {    
     $.post(url, function( data ) {
        //something generic
     })
     .done(function(data) {
       callback(data);
     })
     .fail(function(data) {

       //something generic
     });    
 }

Or you can pass it directly to the done function:

myLoadFunction(url, callback) {    
     $.post(url, function( data ) {
        //something generic
     })
     .done(callback)
     .fail(function(data) {

       //something generic
     });    
 }

Just don't call it 'function' as that is a protected keyword in JavaScript so won't work.

5 Comments

@crush $.post(url, callback) is no good because he'd have to set .done and .fail each time
@crush i was responding to your deleted comment; simply passing the callback to post, as $.post(url, callback), will only execute callback on success. so if OP wants to handle .fail he would need to define the failure callback on every invocation of $.post
@Plato I didn't mean he should ONLY pass it to the $.post. I was showing how he might as well simply pass the callback to the function by reference instead of wrapping it in an anonymous function to execute it. However, if the OP needs to execute some code before the callback, then the inner function makes sense. I'm not sure how you came to the conclusion that you thought I meant that passing the callback to $.post would somehow magically assign it to fail and done too...that's ignorant.
@crush sure, you could do it that way, but I think it goes against OP's request "I dont want to repeat myself" and the spirit of the question, which seems to be 'how can I create a wrapper for this chunk of asynchronous code'
@Plato I wasn't suggesting he do that outside of his encapsulating function..........I didn't understand that he had some other code other than the callback he was passing that he wanted to execute. I didn't find his question to be clear at all. After many comments, I see what he wants to do.
1

I think you mean that you want to have standard calls to $.post and fail but use a different function for done each time.

Your code isn't too far out. One thing you can't do, though, is use function as a variable name: it's a protected word in Javascript. It's common to use fn instead.

You can then pass the function to done:

 myLoadFunction(url, fn) {
     $.post(url, function( data ) {
        //something generic
     })
     .done(fn)
     .fail(function(data) {

       //something generic
     });
 }

Comments

0

I'd do it this way (having control on both success and error handlers):

Snippet:

myLoadFunction(url, successCallback, errorCallback) {
    $.post(url, function( data ) {
        //something generic
     })
     .done(function(data) {
       //what I want to put on my caller function
       successCallback();
     })
     .fail(function(data) {
       //something generic
       errorCallback();
     });
}

Call:

var successHandlerHere = function() {
        console.log('success', arguments);
    },
    errorHandlerHere = function() {
        console.log('error', arguments);
    };

myLoadFunction("myurlblabla", successHandlerHere, errorHandlerHere);

1 Comment

Or as @Royi Namir suggested in another answer below, using deferred objects, being more flexible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.