skip to Main Content

I want to upload the files to Cloudinary and then get the ‘secure_url’ s and insert them into a MySQL database. However my current code immediately execute the SQL function. How to make the SQL function wait till the Cloudinary upload finishes.

Below is the code :

app.post('/create', upload.array('uploaded_file'), function (req, res) {
    console.log(req)

    var wallet = req.body.wallet
    var name = req.body.fname
    var nic = req.body.nic
    var nicfront = req.files[0].path;
    var nicback = req.files[1].path;
    var selfie = req.files[2].path;
    var state = 1

    var frontURL = "temp_string"
    var backURL = "temp_string"
    var selfieURL = "temp_string"

    cloudinary.uploader.upload(nicfront, function (err, result) {
        console.log("Result: ", result);
        frontURL = result.secure_url;
    });
    
    cloudinary.uploader.upload(nicback, function (err, result) {
        console.log("Result: ", result);
        backURL = result.secure_url;
    });

    cloudinary.uploader.upload(selfie, function (err, result) {
        console.log("Result: ", result);
        selfieURL = result.secure_url;
    });

    // Insert into MySQL Database
    db.query("INSERT INTO applications (wallet, name, nic, nicfront, nicback, selfie, state) VALUE (?,?,?,?,?,?,?)", [wallet, name, nic, frontURL, backURL, selfieURL, state], (err, result) => {
        if (err) {
            console.log(err)
        } else {
            res.send("Inserted into MySQL!")
        }
    })
});

app.listen(3001, () => {
    db.connect(function (err) {
        if (err) throw err;
    });
});

2

Answers


  1. Chosen as BEST ANSWER

    I'm not sure if this is the best way to fix this, but somehow it worked. I'm sharing it here just in case someone finds it useful in the future.

    app.post('/create', upload.array('uploaded_file'), function (req, res) {
        console.log(req)
    
        var wallet = req.body.wallet
        var name = req.body.fname
        var nic = req.body.nic
        var nicfront = req.files[0].path;
        var nicback = req.files[1].path;
        var selfie = req.files[2].path;
        var state = 1
    
        cloudinary.uploader.upload(nicfront, function (err, result) {
            console.log("Result: ", result);
            frontURL = result.secure_url;
    
            cloudinary.uploader.upload(nicback, function (err, result) {
                console.log("Result: ", result);
                backURL = result.secure_url;
    
                cloudinary.uploader.upload(selfie, function (err, result) {
                    console.log("Result: ", result);
                    selfieURL = result.secure_url;
                }).then(() => {
                    // Insert into MySQL Database
                    db.query("INSERT INTO applications (wallet, name, nic, nicfront, nicback, selfie, state) VALUE (?,?,?,?,?,?,?)", [wallet, name, nic, frontURL, backURL, selfieURL, state], (err, result) => {
                        if (err) {
                            console.log(err)
                        } else {
                            res.send("Inserted into MySQL!")
                        }
                    })
                });
            });
        });
    });
    
    app.listen(3001, () => {
        db.connect(function (err) {
            if (err) throw err;
            console.log("Connected to MySQL!");
        });
    });
    

  2. Node.js I/O is async, so each of your lines starts uploading and moves onto the next line. Use something like async.parallel to manage the flow of your code so it waits for the three uploads to complete before running the insert:

    const async = require('async')
    app.post('/create', upload.array('uploaded_file'), function (req, res) {
        console.log(req)
    
        var wallet = req.body.wallet
        var name = req.body.fname
        var nic = req.body.nic
        var nicfront = req.files[0].path;
        var nicback = req.files[1].path;
        var selfie = req.files[2].path;
        var state = 1
    
        // Run the three uploads in parallel
        async.parallel({
            frontURL: (done) => {
                cloudinary.uploader.upload(nicfront, function (err, result) {
                    console.log("Result: ", result);
                    done(null,result.secure_url);
                });
            },
            backURL: (done) => {
                cloudinary.uploader.upload(nicback, function (err, result) {
                    console.log("Result: ", result);
                    done(null,result.secure_url);
                });
            },
            selfieURL: (done) => {
                cloudinary.uploader.upload(selfie, function (err, result) {
                    console.log("Result: ", result);
                    done(null,result.secure_url);
                });
            }
        }, (err, urls) => {
            // Insert into MySQL Database
            db.query("INSERT INTO applications (wallet, name, nic, nicfront, nicback, selfie, state) VALUE (?,?,?,?,?,?,?)", [wallet, name, nic, urls.frontURL, urls.backURL, urls.selfieURL, state], (err, result) => {
                if (err) {
                    console.log(err)
                } else {
                    res.send("Inserted into MySQL!")
                }
            })
        })
    });
    
    app.listen(3001, () => {
        db.connect(function (err) {
            if (err) throw err;
        });
    });
    

    Edit: you could also switch to using promises with async/await if cloudinary.uploader.upload returns a promise object when not passed a callback. This might make the code more readable, but I used the async module since your existing code is callback-based. Also, make sure to handle those errors! 🙂

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search