0

I want to add mp3, lrc, wav, txt to the server and the folder name would be title and all of the extensions mentioned above would have specified names. As seen in the code, the mp3 would be "vocal.mp3".

addSong(event) {

    jQuery('#addItemSave').text("Please wait!");

    this._service.addSong(this.authorText, this.titleText, this.durationText, this.genre).subscribe(
        res => {
            this.data.push(res.data[0]);
            this.addSongFilesToServer();
    });
}

private addSongFilesToServer() {
    this._service.addSongFilesToServer(this.titleText,
            this.mp3file, this.lrcfile, this.pitchfile, this.thumbfile).subscribe(
        res => {
            console.log("Done! Now hide loading icon or what ever...");
            jQuery('#addItemSave').text("Save");
            jQuery('#addNewSongDialog').modal('hide');
            jQuery('#addNewSongDialog').find("input,textarea,select")
                    .val('')
                    .end()
                .find("input[type=checkbox], input[type=radio]")
                    .prop("checked", "")
                    .end();
    });
}

addSongFilesToServer(title, mp3, lrc, txt, thumb) {
    let url = this._config.ServerWithApiUrl + "uploadFiles";
    let body : FormData = new FormData();
    body.append('mp3', mp3, "vocal.mp3");
    body.append('txt', txt, "pitches.txt");
    body.append('lrc', lrc, "lyric.lrc");
    body.append('thumb', thumb, "thumbnail.png");
    body.append('title', title);
    this._config.headers.delete('Content-Type');

    return this._http.post(url, body, { headers: this._config.headers })
        .map(res => res.json()).catch(function(err){
            throw err;
    });
}

addSong(event) is called when a button is pressed on the page and the all of the files that need to be passed on, are being passed on. The only problem here is that mp3, lrc, wav, txt go all under different folders with their their, for example vocal.mp3.

Just to illustrate, this is what I am getting at the moment :

├───songs
│   ├───vocal
│   │    vocal.mp3
│   ├───pitches
│   │    pitches.txt
...

And this is what I need:

├───songs
│   ├───title
│   │    vocal.mp3
│   │    lyric.lrc
│   │    pitches.txt
...

And the server side:

Router.post('/uploadFiles', (req, res) => {

    var title = req.body.title || "title";

    var storage = multer.diskStorage({
        destination: function (req, file, cb) {
            var dir = "../songs/" + file.originalname.split('.')[0];
            if (!fs.existsSync(dir)){
                fs.mkdirSync(dir);
            }
            cb(null, dir);
        },
        filename: function (req, file, cb) {
            cb(null, file.originalname);
        }
    });

    var upload = multer({ storage : storage}).any();
    upload(req,res,function(err){            
        if(err){            
            return res.status(500).send({ 
                code: 500, message: 'could not upload file: ' + err, error: err });
        }else {
            return res.status(200).send({ 
                code: 200, message: 'All files uploaded!', err: ""});
        }                     
    });       
});
Richard
  • 1,087
  • 18
  • 52

1 Answers1

1

You can see in the example that you actually coded that way

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        var dir = "../songs/" + file.originalname.split('.')[0];
        if (!fs.existsSync(dir)){
            fs.mkdirSync(dir);
        }
        cb(null, dir);
    },
    filename: function (req, file, cb) {
        cb(null, file.originalname);
    }
});

The file.originalname.split('.')[0] actually splits the extension and takes the filename.

so it will be var dir = "../songs/" + title; plain and simple.

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        ////////////////////////////
        var dir = "../songs/" + title;
        ///////////////////////
        if (!fs.existsSync(dir)){
            fs.mkdirSync(dir);
        }
        cb(null, dir);
    },
    filename: function (req, file, cb) {
        cb(null, file.originalname);
    }
});

Also, body-parser doesn't handle multipart bodies, which is what FormData is submitted as. So the req.body.title will not work.

Check this for reference: How to handle FormData from express 4
Most probably you will need to send the title in another way

Aritra Chakraborty
  • 12,123
  • 3
  • 26
  • 35
  • I know I already accepted your answer but why is the folder name always "title" now. It used to get the correct title when inserted but now its always "title". Is it because there is a string "title" added and it is not getting the `req.body.title" ? Although it used to get it before – Richard Aug 09 '18 at 20:32
  • can you check `console.log(title)` and see if you're getting correctly or not. – Aritra Chakraborty Aug 09 '18 at 22:44
  • 1
    edited answer, check if it answers your query or ask another question – Aritra Chakraborty Aug 09 '18 at 22:55