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"
    });
}
zee
  • 536
  • 2
  • 5
  • 26
  • 1
    `file.detectFileType.call(file);` --- this is the same as `file.detectFileType();` – zerkms Sep 09 '16 at 01:30
  • As of your problem `var self = this;` right before `magic.detectFile...` and use `self` in the anonymous function. Then http://stackoverflow.com/q/3127429/251311 – zerkms Sep 09 '16 at 01: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 – Jaromanda X Sep 09 '16 at 01:33
  • I've made the changes as recommended and checked out the links. Still can't get it to work. Code has been edited. – zee Sep 09 '16 at 01:53
  • What's unclear about Jaromanda X's comment? – Felix Kling Sep 09 '16 at 02:10
  • How do I fix it is what's unclear – zee Sep 09 '16 at 02:16

1 Answers1

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);
    });
}
mscdex
  • 93,083
  • 13
  • 170
  • 135
  • 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. – zee Sep 09 '16 at 16:53