2

I am trying to pass one function into another so that I can call it when an ajax call has finished, but I get an error saying that the function I want to call is not a function.

File1 (Loaded first)

function functionOne() {
    //Some Code
}

File2 (Loaded second and contains ajax call)

function functionTwo(functionOne) {
    functionOne();
}

functionTwo();

I get the console error of TypeError: functionOne is not a function

My question is two fold:

  1. Why is functionOne out of scope in the second function?
  2. Is this the best way of ensuring the ajax call has finished before running my first function code?
6
  • 5
    How do you call functionTwo ? Commented Jun 16, 2015 at 11:23
  • 1
    "1. Why is functionOne out of scope in the second function?" Nothing's out of scope. You have a parameter named functionOne that shadows the global. "2. Is this the best way of ensuring the ajax call has finished before running my first function code?" Depends what you mean. You're not really showing what you're doing. Commented Jun 16, 2015 at 11:31
  • @Tushar Sorry, it is called afterwards. Amended Commented Jun 16, 2015 at 11:31
  • @squint What do you mean by "Shadows the global" ? Commented Jun 16, 2015 at 11:33
  • 1
    You're trying to access functionOne inside functionTwo. The problem is functionTwo defines a parameter with the same name as functionOne. The identifier name resolution is such that the variable/parameter closest to its point of use will be used. Therefore, you're using the function parameter because it blocks (shadows) the global with the same name. And because you're not passing anything to that parameter, it's undefined, which isn't a function. Just ditch that function parameter and it'll work. Commented Jun 16, 2015 at 11:40

1 Answer 1

3

In functionTwo, you shadow functionOne as you declare it as argument: the code in functionTwo only sees this new variable, not the global one with the same name.

But your approach is the wrong one, it won't ensure the order of execution you're looking for.

jQuery's ajax function returns a promise, which is a way to deal with asynchronous functions and have some function be executed when an ajax call has finished.

If you want functionTwo to start an ajax call and then call functionOne, you may do this:

function functionOne() {
}

function functionTwo() {
    return $.ajax({ // don't forget the return
       // many parameters here
    }).then(function(data){
        // use the data here
    });
}

functionTwo().then(functionOne);

This ensures functionOne is called only after the ajax call started in functionTwo has finished.

If you want to use the old fashioned way and pass the function as argument, do it like this:

function functionOne() {
}

function functionTwo(callback) {
    $.ajax({
       // many parameters here
    }).then(function(data){
        // use the data here
    }).then(callback);
}

functionTwo(functionOne);

But it's 2015, you'd better start looking at deferreds and promises ;)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your response. I did look at the promise but wasn't sure exactly how to execute it. For future reference, if I did want to pass one function into another rather than shadowing it, how would I do this?

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.