Search code examples
javascriptnode.jscallbacknode-async

Error of callback is not a function at Timeout._onTimeout


CODE: Named functions to recuse:

console.log('before');

getUser(1, getRepositories);
    // console.log('User',user);

function getRepositories(user) {
    //  console.log(user);
    getRepositories(user.gitHubUsername, getCommits);
}

function getCommits(repos) {
    getCommits(repo, displayCommits);
}

function displayCommits(commits) {
    console.log(commits);
}

console.log('after');

function getUser(id, callback) {
   setTimeout(() => {
    console.log('reading a user from databse...');
    callback({ id: id, gitHubUsername: 'mosh'});
}, 2000);
}

function getRepositories(username, callback) {
    setTimeout(() => { 
    console.log('calling GitHub API...');
    callback(['repo1', 'repo2', 'repo3']);
},2000);
}

function getCommits(repo, callback) {
    setTimeout(() => { 
    console.log('calling GitHub API...');
    callback(['commit']);
},2000);
}

OUTPUT: before after reading a user from databse... calling GitHub API... C:\Users\jaini\node\async-demo\index.js:31 callback(['repo1', 'repo2', 'repo3']); ^

TypeError: callback is not a function
    at Timeout._onTimeout (C:\Users\jaini\node\async-demo\index.js:31:5)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)

Solution

  • Just as you don't want your kids/pets/whatever have the same name, you should not have functions with the same name in the same scope. That poor JS engine could not decide which getRepositories or getCommits function you wanted to run. Try to rename these and you're good to go:

    console.log('before');
    
    getUser(1, getRepositoriesByUser);
    
    function getRepositoriesByUser(user) {
      getRepositories(user.gitHubUsername, getCommitsByRepo);
    }
    
    function getCommitsByRepo(repo) {
      getCommits(repo, displayCommits);
    }
    
    function displayCommits(commits) {
      console.log(commits);
    }
    
    console.log('after');
    
    function getUser(id, callback) {
      setTimeout(() => {
        console.log('reading a user from database...');
        callback({ id, gitHubUsername: 'mosh' });
      }, 2000);
    }
    
    function getRepositories(username, callback) {
      setTimeout(() => {
        console.log('calling GitHub API to get repos...');
        callback(['repo 1', 'repo 2', 'repo 3']);
      }, 2000);
    }
    
    function getCommits(repo, callback) {
      setTimeout(() => {
        console.log('calling GitHub API to get commits...');
        callback(['commit A', 'commit B']);
      }, 2000);
    }