0

I'm pretty confident that there is something with this that I'm doing wrong. This question has been asked before, but even after reviewing the other questions and answers, I still can't get it to work.

Basically the issue is that I can't set file.fileType to be the value I need it to be from within the callback function within magic.detectFileType.

var Magic = mmm.Magic,
    magic = new Magic(mmm.MAGIC_MIME_TYPE),

for (var i in files){
    var file = new File(files[i])
    file.detectFileType();

    commandSelf.log("File Type: " + file.fileType);
    commandSelf.log("File Name: " + file.filename);
    commandSelf.log("Full Path: " + file.fullPath);
} 

var File = function(filename){
    this.filename = filename;
    this.fullPath = null;
    this.fileType = null;
};

File.prototype.detectFileType = function(){
    this.fullPath = path + "/" + this.filename;
    var self = this;

    // Make sure this is an appropriate image file type
    magic.detectFile(this.fullPath, function(err, result){
        self.fileType = "test"
    });
}
6
  • 1
    file.detectFileType.call(file); --- this is the same as file.detectFileType(); Commented Sep 9, 2016 at 1:30
  • As of your problem var self = this; right before magic.detectFile... and use self in the anonymous function. Then stackoverflow.com/q/3127429/251311 Commented Sep 9, 2016 at 1:31
  • 4
    if magic.detectFile is asynchronous then you'll be logging fileType before it is set to anything in the magic.detectFile callback - based on the description of mmmagic - An async libmagic binding, that is at least the main problem - not sure about the rest of the code as others have mentioned above Commented Sep 9, 2016 at 1:33
  • I've made the changes as recommended and checked out the links. Still can't get it to work. Code has been edited. Commented Sep 9, 2016 at 1:53
  • What's unclear about Jaromanda X's comment? Commented Sep 9, 2016 at 2:10

1 Answer 1

1

A more appropriate solution would be to have detectFileType accept a callback or return a Promise so that you know when the asynchronous task has completed and you can safely check the File instance properties. For example:

var Magic = mmm.Magic;
var magic = new Magic(mmm.MAGIC_MIME_TYPE);

files.forEach(function(file) {
    file = new File(file);
    file.detectFileType(function(err) {
        if (err) throw err;
        commandSelf.log("File Type: " + file.fileType);
        commandSelf.log("File Name: " + file.filename);
        commandSelf.log("Full Path: " + file.fullPath);
    });
});

var File = function(filename){
    this.filename = filename;
    this.fullPath = null;
    this.fileType = null;
};

File.prototype.detectFileType = function(cb){
    this.fullPath = path + "/" + this.filename;
    var self = this;

    // Make sure this is an appropriate image file type
    magic.detectFile(this.fullPath, function(err, result){
        self.fileType = "test"
        cb(err);
    });
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this makes a lot more sense. Works well. The concept of callbacks makes sense to me, but looks like there's more to learn. Correct me if I'm wrong, but basically you need to set callbacks within callbacks when calling a function that calls an async function.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.