Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8740977
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T11:13:36+00:00 2026-06-13T11:13:36+00:00

DEFINITION File#createDirectoriesFromJSON (json, cb); json: JSON object. cb: Function. Parameters: error (Error), created (Boolean,

  • 0

DEFINITION

File#createDirectoriesFromJSON (json, cb);

json: JSON object.

cb: Function. Parameters: error (Error), created (Boolean, true if at least one directory has been created).

Supose that the File class contains a property named _path that contains the path of a directory.

USAGE

var json = {
    b: {
        c: {
            d: {},
            e: {}
        },
        f: {}
    },
    g: {
        h: {}
    }
};

//this._path = "."
new File (".").createDirectoriesFromJSON (json, function (error, created){
    console.log (created); //Prints: true

    //callback binded to the File instance (to "this"). Hint: cb = cb.bind (this)
    this.createDirectoriesFromJSON (json, function (error, created){
        console.log (created); //Prints: false (no directory has been created)
    });
});

RESULT

Under “.” the directory tree showed in the json object has been created.

./b/c/d
./b/c/e
./b/f
./b/g/h

IMPLEMENTATION

This is what I have without async.js:

File.prototype.createDirectoriesFromJSON = function (json, cb){
    cb = cb.bind (this);

    var created = false;
    var exit = false;

    var mkdir = function (path, currentJson, callback){
        var keys = Object.keys (currentJson);
        var len = keys.length;
        var done = 0;

        if (len === 0) return callback (null);

        for (var i=0; i<len; i++){
            (function (key, i){
                var dir = PATH.join (path, key);
                FS.mkdir (dir, function (mkdirError){
                    exit = len - 1 === i;

                    if (mkdirError && mkdirError.code !== "EEXIST"){
                        callback (mkdirError);
                        return;
                    }else if (!mkdirError){
                        created = true;
                    }

                    mkdir (dir, currentJson[key], function (error){
                        if (error) return callback (error);
                        done++;
                        if (done === len){
                            callback (null);
                        }
                    });
                });
            })(keys[i], i);
        }
    };

    var errors = [];

    mkdir (this._path, json, function (error){
        if (error) errors.push (error);
        if (exit){
            errors = errors.length === 0 ? null : errors;
            cb (errors, errors ? false : created);
        }
    });
};

Just for curiosity I want to rewrite the function using async.js. The problem here is that the function is recursive and parallel. For example, the “b” folder is created in parallel with “g”. The same for “b/c” and “b/f”, and “b/c/d” and “b/c/e”.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T11:13:37+00:00Added an answer on June 13, 2026 at 11:13 am

    My attempt:

    var _path  = require('path');
    var _fs    = require('fs');
    var _async = require('async');
    
    function File() {
        this._path = __dirname + '/test';
    }
    
    File.prototype.createDirectoriesFromJSON = function(json, cb) {
        var created = [], errors  = [];
    
        function iterator(path, currentJson, key, fn){
            var dir = _path.join(path, key);
    
            _fs.mkdir(dir, function(mkdirError) {
    
                if(mkdirError && mkdirError.code !== "EEXIST") {
                    errors.push(mkdirError);
                } else if(!mkdirError) {
                    created.push(dir);
                }
    
                mkdir(dir, currentJson[key], fn);
            });
        }
    
        function mkdir(path, currentJson, callback) {
            var keys = Object.keys(currentJson);
    
            if(keys.length === 0) return callback(null);
    
            _async.forEach(keys, iterator.bind(this, path, currentJson), callback);
        }
    
        mkdir(this._path, json, cb.bind(this, errors, created));
    };
    
    
    new File().createDirectoriesFromJSON({
        b: {
            c: {
                d: {},
                e: {}
            },
            f: {}
        },
        g: {
            h: {}
        }
    }, function(errors, successes) {
        // errors is an array of errors
        // successes is an array of successful directory creation
        console.log.apply(console, arguments);
    });
    

    Tested with:

    $ rm -rf test/* && node test.js && tree test
    
    [] [ '/Users/fg/Desktop/test/b',
      '/Users/fg/Desktop/test/g',
      '/Users/fg/Desktop/test/b/c',
      '/Users/fg/Desktop/test/b/f',
      '/Users/fg/Desktop/test/g/h',
      '/Users/fg/Desktop/test/b/c/d',
      '/Users/fg/Desktop/test/b/c/e' ] null
    test
    |-- b
    |   |-- c
    |   |   |-- d
    |   |   `-- e
    |   `-- f
    `-- g
        `-- h
    
    7 directories, 0 files
    

    Notes:

    • Since errors.push(mkdirError); means that the directory couldn’t be created, return fn(null); could be appended to it to stop the directory creation from this branch.
    • cb will receive a third argument that will always be null.
    • I would preferably use wrench .mkdirSyncRecursive() for this kind of task, or substack async mkdirp.

    [Update] Using mkdirp and lodash (or underscore) the code can be even clearer:

    var _path   = require('path');
    var _fs     = require('fs');
    
    var _async  = require('async');
    var _mkdirp = require('mkdirp');
    var _       = require('lodash'); // or underscore
    
    function File() {
        this._path = __dirname + '/test';
    }
    
    File.prototype.flattenJSON = function(json){
        function walk(path, o, dir){
            var subDirs = Object.keys(o[dir]);
            path +=  '/' + dir;
    
            if(subDirs.length === 0){
                return path;
            }
    
            return subDirs.map(walk.bind(null, path, o[dir]));
        }
    
        return _.flatten(Object.keys(json).map(walk.bind(null, this._path, json)));
    };
    
    File.prototype.createDirectoriesFromJSON = function(json, cb) {
        var paths   = this.flattenJSON(json)
        ,   created = []
        ,   errors  = [];
    
        function iterator(path, fn){
            _mkdirp(path, function(mkdirError) {
    
                if(mkdirError && mkdirError.code !== "EEXIST") {
                    errors.push(mkdirError);
                } else if(!mkdirError) {
                    created.push(path);
                }
    
                return fn(null);
            });
        }
    
        _async.forEach(paths, iterator, cb.bind(this, errors, created));
    };
    
    
    new File().createDirectoriesFromJSON({
        b: {
            c: {
                d: {},
                e: {}
            },
            f: {}
        },
        g: {
            h: {}
        }
    }, function(errors, successes) {
        // errors is an array of error
        // successes is an array of successful directory creation
        console.log.apply(console, arguments);
    });
    

    Tested with:

    $ rm -rf test/* && node test2.js && tree test
    
    [] [ '/Users/fg/Desktop/test/b/f',
      '/Users/fg/Desktop/test/g/h',
      '/Users/fg/Desktop/test/b/c/d',
      '/Users/fg/Desktop/test/b/c/e' ] null
    test
    |-- b
    |   |-- c
    |   |   |-- d
    |   |   `-- e
    |   `-- f
    `-- g
        `-- h
    
    7 directories, 0 files
    

    Note:

    • iterator could be removed by using partial function application, however underscore/lodash only support partial from left to right thus I did not wanted to require another library to do so.
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

When compiling a c file that uses old style function definition like int foo(a)
Created basic C++ DLL and exported names using Module Definition file (MyDLL.def). After compilation
Created a web role project on Azure. Looking at the service definition file I
Given a SSRS report definition file with an embedded image in it, just wondering
I have an XML Schema Definition file .XSD who's elements are in Spanish. I
I've only recently noticed the Filter element in the definition file for a SharePoint
Whenever I wish to debug a single report (.rdl file, Report Definition file), it
I have a macro definition in header file like this: // header.h ARRAY_SZ(a) =
Here is my route definition in the bootstrap file: $router = $this->frontController->getRouter(); $route =
I have a keyboard definition in an xml file in /res/xml which looks something

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.