0

I'm writing a small plugin to add meta info to collections in Metalsmith. Though what I'm struggling with is setting a variable. The variable doesn't have to be global, I just need to assign the string of the first found file within the glob callback to a variable in scope of the outer function.

Below is the whole thing. The problem is within the glob callback:

files[filepath].sdklib = getGlobRes();

Within the glob, a correct path is returned. The log prints "ios_libs_1.3.0.tar.gz" for example. But it's assignment is "lost". Printing files[filepath].sdklib outside the scope of the glob will print "blah".

Why is my assignment lost?

var globRes = "";

function setGlobRes(newVal) {
    globRes = newVal;
}

function getGlobRes() {
    return globRes;
}

module.exports = function(opts) {

    opts = opts || {};
    opts.absolute = opts.absolute !== false;
    // Adds filename, platform, changelog and version properties to a file object
    // if it matches .gz
    return function (files, metalsmith, done) {
    for (var filepath in files) {
        if (files.hasOwnProperty(filepath) && filepath.split('.').pop() == 'gz') {
            var link = './' + filepath.replace(/\\/g, '/');
            files[filepath].link = link;
            files[filepath].sdklib = "empty";
            var components = filepath.split('/');
            var dir = getFileDirectory(filepath);
             setGlobRes("blah");
            glob("src/" + dir + "/" + "*libs*.tar.gz", function (er, filesFound) {
              setGlobRes(filesFound[0]);
              console.log("found: " + filesFound[0]);
            })
            files[filepath].sdklib = getGlobRes();
            // console.log("dir: " + dir);
//          console.log("filepath: " + filepath);
            var filename = components.pop(); 
            var changelog = components.join('/') + '/changelog.md';
//             var filesInDir = getFilesInDir(dir);
            var version = components.pop();
            var platform = components.pop();
            files[filepath].filename = filename;
            files[filepath].version = version;
            files[filepath].platform = platform;
            files[filepath].filename = filename;
            if (files[changelog] != undefined) {
                files[filepath].changelog = files[changelog].contents;
                }
                else {
                    console.log(changelog + ' is missing');
                }
            }
        }
    done();
    };
};
tommybananas
  • 5,718
  • 1
  • 28
  • 48
benjist
  • 2,740
  • 3
  • 31
  • 58
  • Put all the code that needs access to the result *inside* the callback. – Felix Kling May 18 '16 at 18:43
  • Your glob function's callback function is asynchronous so this code `files[filepath].sdklib = getGlobRes();` is called before `setGlobRes(filesFound[0]);` this means all the code below glob(...) needs to go inside glob's callback – Molda May 18 '16 at 18:46
  • Well, since this is a plugin, I just cannot make this call async... – benjist May 18 '16 at 19:53

0 Answers0