1

This is the file "path-info.js" that has 2 functions: pathInfo & callback. Pathinfo collects all info about file from path in the object "info", callback gets that object and returns it. Code:

"use strict";
const fs = require("fs");

let getInfo = function (err, someObject) {
    if (err) throw err;
    return someObject;
};

function pathInfo(path, callback) {
  let info = {};

  info.path = path; // write path info

  fs.stat(path, (err, type) => { // write type info
    if (type.isFile()) {
      info.type = "file";
    }
    if (type.isDirectory()) {
      info.type = "directory";
    } else {
      info.type = "undefined";
    }
  });

  fs.stat(path, (err, type) => { // write content info if it is file
    if (type.isFile()) {
      fs.readFile(path, "utf8", (err, content) => {
        info.content = content;
      });
    } else {
      info.content = "undefined";
    }
  });

  fs.stat(path, (err, type) => { // write childs if it is directory
    if (type.isDirectory()) {
      fs.readdir(path, (err, childs) => {
        info.childs = childs
      });
    } else {
      info.childs = "undefined";
    }
  });

  getInfo(null, info); // callback returns object "info"
}

module.exports = pathInfo;

I use my callback function as it was shown, for instance, here: nodeJs callbacks simple example. Still, this code does not work and I do not why.

I call this code using file "test.js", here is the code:

const pathInfo = require('./path-info');
function showInfo(err, info) {
  if (err) {
    console.log('Error occurred');
    return;
  }

  switch (info.type) {
    case 'file':
      console.log(`${info.path} — is File, contents:`);
      console.log(info.content);
      console.log('-'.repeat(10));
      break;
    case 'directory':
      console.log(`${info.path} — is Directory, child files:`);
      info.childs.forEach(name => console.log(`  ${name}`));
      console.log('-'.repeat(10));
      break;
    default:
      console.log('Is not supported');
      break;
  }
}

pathInfo(__dirname, showInfo);
pathInfo(__filename, showInfo);

So the logic is that I need to give my callback the object that contains some info about directory or file. Depending on that, some console.logs will be displayed.

Any help will be appreciated!

UPD: updated the code, just renamed my "callback" function to "getInfo".

Evgeny Kobzev
  • 89
  • 1
  • 12
  • Define "does not work'. – Dave Newton Jul 28 '17 at 11:42
  • This is because you declared a variable called `callback` in your `path-info.js`. Rename it and it will solve your problem. – ADreNaLiNe-DJ Jul 28 '17 at 11:42
  • What error message are you getting? – JSON Derulo Jul 28 '17 at 11:53
  • @DaveNewton At this moment it writes "Is not supported", but I am 100% sure that there should be another console.log (not default case..) – Evgeny Kobzev Jul 28 '17 at 11:56
  • @ADreNaLiNe-DJ renamed it to "getInfo" (just another name), still does not work.. – Evgeny Kobzev Jul 28 '17 at 11:59
  • could you log the complete info-object in your callback – Bee157 Jul 28 '17 at 12:01
  • @EvgenyKobzev Can you update the code of the question with the modification ? It will avoid other to answer like me ;o) – ADreNaLiNe-DJ Jul 28 '17 at 12:02
  • @Satpal sure and I use its asynchronous structure, in callback I assign info.type the value in relation to what type is it. I think there is no mistake in that piece of code. – Evgeny Kobzev Jul 28 '17 at 12:03
  • @EvgenyKobzev @SatPal means that "when you call the callback all your `fs.stat` calls are not ended, so the object you pass to `callback` is empty => `{}`". – ADreNaLiNe-DJ Jul 28 '17 at 12:05
  • @ADreNaLiNe-DJ I updated the file.. plus I logged info-object in the callback and it send me that: `{ path: '/Users/kobz/WebstormProjects/netology' } { path: '/Users/kobz/WebstormProjects/netology/test.js' }` There is only "path" property, while others are missing.. – Evgeny Kobzev Jul 28 '17 at 12:07
  • @EvgenyKobzev This what we are saying about the `asynchrony` of your calls: not all calls are ficniehd when you call `callback` so your object is empty or not complete. – ADreNaLiNe-DJ Jul 28 '17 at 12:10
  • @ADreNaLiNe-DJ sadly, but I am not allowed to use promises in this task :(( So I should try to solve that task whit what I´ve got..( – Evgeny Kobzev Jul 28 '17 at 12:12
  • @EvgenyKobzev And what about the posted answer from Kamesh ? – ADreNaLiNe-DJ Jul 28 '17 at 12:14
  • @ADreNaLiNe-DJ I need to solve that task without external modules :( Surely this is the right one, but I´ve got restrictions.. – Evgeny Kobzev Jul 28 '17 at 12:17
  • @Bee157 now it logs `{ path: '/Users/kobz/WebstormProjects/netology' } { path: '/Users/kobz/WebstormProjects/netology/test.js' }` and as @ADreNaLiNe-DJ noticed my callbacks are not finished when i call getInfo callback to return info object. – Evgeny Kobzev Jul 28 '17 at 12:20
  • In your function pathInfo, replace getInfo(null, info); with callback(null, info); Your callback is function send to your internal function, so execute it. you call it callback, execute callback. – Plaute Jul 28 '17 at 12:29

2 Answers2

0

A callback is a function you pass as parameter to another function.

In your case, your second parameter is function showInfo which is your callback. Your function pathInfo accepts two parameters, second is showInfo.

So when you call it, you execute code within showInfo with some parameters, usually err, then something else.

In your case, you name second parameter "callback" in showInfo, so you have to execute it with asked parameters (err and info).

Example:

function myfunc (parameter,cb) {
    cb(null,{});
}

myfunc("one", function (err,res) {
    console.log(err);
});

where "cb" in "myfunc" is function sent as second parameter.

It can be write like this as you did it:

var cb = function (err,res) {
    console.log(err);
}

myfunc("one",cb);
Plaute
  • 4,669
  • 2
  • 17
  • 19
0

In case anyone is interested.. I found a solution and it works! As @ADreNaLiNe-DJ correctly stated, my callbacks are not finished when i call getInfo callback to return info object. So the way out is to change my level of abstraction: all i´ve done is pasted my callbacks inside functions. See that code:

"use strict";
const fs = require("fs");

let pathInfo = (path, callback) => {
  let info = {};
  info.path = path;

  fs.stat(path, (err, type) => {
    if (err) throw err;
    if (type.isFile()) {
      info.type = "file";
      fs.readFile(path, "utf8", (err, content) => {
        info.content = content;
        info.childs = undefined;
        callback(err, info);
      });
    }
    if (type.isDirectory()) {
      info.type = "directory";
      fs.readdir(path, (err, childs) => {
        info.childs = childs;
        info.content = undefined;
        callback(err, info);
      });
    }
  });
};

let showInfo = (err, info) => {     // Отсюда и ниже вставлен код из текста
  if (err) {                        // из домашнего задания
    console.log('Возникла ошибка при получении информации');
    return;
  }

  switch (info.type) {
    case 'file':
      console.log(`${info.path} — является файлом, содержимое:`);
      console.log(info.content);
      console.log('-'.repeat(10));
      break;
    case 'directory':
      console.log(`${info.path} — является папкой, список файлов и папок в ней:`);
      info.childs.forEach(name => console.log(`  ${name}`));
      console.log('-'.repeat(10));
      break;
    default:
      console.log('Данный тип узла не поддерживается');
      break;
  }
};

pathInfo(__dirname, showInfo);
pathInfo(__filename, showInfo);

PS: sorry for Russian console.logs, hope it won't disturb you (they don't bring any value anyway into understanding how it works)

Evgeny Kobzev
  • 89
  • 1
  • 12