14

I am trying learn nodejs and stumble upon this error

TypeError: callback is not a function

when I am trying to call the server using this command.

curl http://localhost:8090/albums.json

and here is the code for my server.js

var http = require('http'),
  fs = require('fs');

function load_album(album_name, callback) {
  fs.readdir("albums/", +album_name, (err, files) => {
    if (err) {
      if (err.code == "ENOENT") {
        callback(make_error("no_such_album", "That album doesn't exist"));
      } else {
        callback(make_error("can't load album", "The server is broken"));
      }
    } else {
      //callback(null, files);
      var only_files = [];
      var path = 'albums/${album_name}/';

      var iterator = (index) => {
        if (index == files.length) {
          var obj = {
            short_name: album_name,
            photos: only_files
          };
          callback(null, obj);
          return;
        }

        fs.stat(path + files[index], (err, stats) => {
          if (!err && stats.isFile()) {
            only_files.push(files[index]);
          }
          iterator(index + 1);
        });
      };
      iterator(0);
    }
  });
}


function handle_incoming_request(req, res) {
  console.log("incoming request: " + req.method + " " + req.url);

  if (req.url == '/albums.json') {
    load_album((err, albums) => {
      if (err) {
        res.writeHead(500, {
          "Content-Type": "application/json "
        });
        res.end(JSON.stringify({
          code: "cant_load_albums",
          message: err.message
        }));
      } else {
        var output = {
          error: null,
          data: {
            albums: albums
          }
        };
        res.writeHead(200, {
          "Content-Type": "application/json"
        });
        res.end(JSON.stringify(output) + "\n");
      }
    });
  } else if (req.url.substr(0, 7) == '/albums' && req.url.substr(req.url.length - 5) == '.json') {
    //user is requesting contents of album
    load_album(req.url.substr(7, req.url.length - 12), (err, photos) => {
      if (err) {
        res.writeHead(500, {
          "Content-type": "application/json"
        });
        res.end(JSON.stringify(err));
      } else {
        var output = {
          error: null,
          data: {
            photos: photos
          }
        };
        res.writeHead(200, {
          "Content-Type": application / json
        });
        res.end(JSON.stringify(output) + "\n");
      }
    });
  } else {
    res.writeHead(404, {
      "Content-type": "application/json"
    });
    res.end(JSON.stringify({
      code: "no_such_page",
      message: "No such page"
    }));
  }
}
var s = http.createServer(handle_incoming_request);
s.listen(8090);

can you tell me what's wrong with my code that I got an error telling me callback isn't a function?

thanks though

for more formatted code then you can go here https://jsfiddle.net/02dbx6m9/

3
  • 2
    You are sending only one parameter into load_album instead of two in the first call, so that callback will always be undefined. Commented Feb 14, 2017 at 5:06
  • also, you're putting 3 params into fs.readdir(...) instead of 2 Commented Feb 14, 2017 at 5:08
  • which params I should delete then? Commented Feb 14, 2017 at 5:21

3 Answers 3

9

var http = require('http'),
  fs = require('fs');

function load_album(album_name, callback) {
  fs.readdir("albums/", +album_name, (err, files) => {
    if (err) {
      if (err.code == "ENOENT") {
        callback(make_error("no_such_album", "That album doesn't exist"));
      } else {
        callback(make_error("can't load album", "The server is broken"));
      }
    } else {
      //callback(null, files);
      var only_files = [];
      var path = 'albums/${album_name}/';

      var iterator = (index) => {
        if (index == files.length) {
          var obj = {
            short_name: album_name,
            photos: only_files
          };
          callback(null, obj);
          return;
        }

        fs.stat(path + files[index], (err, stats) => {
          if (!err && stats.isFile()) {
            only_files.push(files[index]);
          }
          iterator(index + 1);
        });
      };
      iterator(0);
    }
  });
}


function handle_incoming_request(req, res) {
  console.log("incoming request: " + req.method + " " + req.url);

  if (req.url == '/albums.json') {
    load_album("ALBUM NAME", (err, albums) => {
      if (err) {
        res.writeHead(500, {
          "Content-Type": "application/json "
        });
        res.end(JSON.stringify({
          code: "cant_load_albums",
          message: err.message
        }));
      } else {
        var output = {
          error: null,
          data: {
            albums: albums
          }
        };
        res.writeHead(200, {
          "Content-Type": "application/json"
        });
        res.end(JSON.stringify(output) + "\n");
      }
    });
  } else if (req.url.substr(0, 7) == '/albums' && req.url.substr(req.url.length - 5) == '.json') {
    //user is requesting contents of album
    load_album("Album Name", req.url.substr(7, req.url.length - 12), (err, photos) => {
      if (err) {
        res.writeHead(500, {
          "Content-type": "application/json"
        });
        res.end(JSON.stringify(err));
      } else {
        var output = {
          error: null,
          data: {
            photos: photos
          }
        };
        res.writeHead(200, {
          "Content-Type": application / json
        });
        res.end(JSON.stringify(output) + "\n");
      }
    });
  } else {
    res.writeHead(404, {
      "Content-type": "application/json"
    });
    res.end(JSON.stringify({
      code: "no_such_page",
      message: "No such page"
    }));
  }
}
var s = http.createServer(handle_incoming_request);
s.listen(8090);

You forgot to pass album name parameter in load_album method. That's why album_name parameter is assigned the actual callback, while callback parameter remains undefined.

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

1 Comment

load_album("ALBUM NAME", (err, albums) => {})
7

Here is the root cause of your issue:

load_album((err, albums) => {
    // ...
});

The signature for the function requires two parameters, yet you're only passing the first one:

function load_album(album_name, callback) {}

Therein, once called, callback will be undefined, yet you're trying to treat it as a callable. Here's a more succint example of how to reproduce the error:

function foo(bar, baz) {
  baz() 
}

foo(() => {})

1 Comment

so where should I add another parameters? I don't really understand this.
0

var http = require('http'),
  fs = require('fs');

function load_album(album_name, callback) {
  fs.readdir("albums/", +album_name, (err, files) => {
    if (err) {
      if (err.code == "ENOENT") {
        callback(make_error("no_such_album", "That album doesn't exist"));
      } else {
        callback(make_error("can't load album", "The server is broken"));
      }
    } else {
      //callback(null, files);
      var only_files = [];
      var path = 'albums/${album_name}/';

      var iterator = (index) => {
        if (index == files.length) {
          var obj = {
            short_name: album_name,
            photos: only_files
          };
          callback(null, obj);
          return;
        }

        fs.stat(path + files[index], (err, stats) => {
          if (!err && stats.isFile()) {
            only_files.push(files[index]);
          }
          iterator(index + 1);
        });
      };
      iterator(0);
    }
  });
}


function handle_incoming_request(req, res) {
  console.log("incoming request: " + req.method + " " + req.url);

  if (req.url == '/albums.json') {
    load_album((err, albums) => {
      if (err) {
        res.writeHead(500, {
          "Content-Type": "application/json "
        });
        res.end(JSON.stringify({
          code: "cant_load_albums",
          message: err.message
        }));
      } else {
        var output = {
          error: null,
          data: {
            albums: albums
          }
        };
        res.writeHead(200, {
          "Content-Type": "application/json"
        });
        res.end(JSON.stringify(output) + "\n");
      }
    });
  } else if (req.url.substr(0, 7) == '/albums' && req.url.substr(req.url.length - 5) == '.json') {
    //user is requesting contents of album
    load_album(req.url.substr(7, req.url.length - 12), (err, photos) => {
      if (err) {
        res.writeHead(500, {
          "Content-type": "application/json"
        });
        res.end(JSON.stringify(err));
      } else {
        var output = {
          error: null,
          data: {
            photos: photos
          }
        };
        res.writeHead(200, {
          "Content-Type": application / json
        });
        res.end(JSON.stringify(output) + "\n");
      }
    });
  } else {
    res.writeHead(404, {
      "Content-type": "application/json"
    });
    res.end(JSON.stringify({
      code: "no_such_page",
      message: "No such page"
    }));
  }
}
var s = http.createServer(handle_incoming_request);
s.listen(8090);

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

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