0

First and foremost I accept that this issue is not something new for developers and there are thousands of post in Stackoverflow.(Specially this post ) I'm new to web development. When I read those post I don't understand what they're saying. I need a very simple solution since I'm an amateur.

As you know sometimes you need to retrieve data from your database (in my situation it was MongoDB GridFS) and sometimes this cause problem.

The function below(getAll) is meant to retrieve all pictures in my GridFS, push them into an array (images) and finally, call the callback function with the answer:

    function getAll(callback) {
    var images = [];
    db.collection('fs.files').find({}).toArray(function (err, files) {
        var Files = files;
        for (var i = 0; i < Files.length; i++) {
            getFileById(Files[i]._id, function (err, img) {
                if (err) {
                    callback(err, null);
                }
                else images.push(img);
            })
        }
    });
    setTimeout(function () {
        callback(null, images);
    }, 1000)
}

At first, I didn't use setTimeout and Got the problem that my images array was always empty. But when I used the setTimeout function everything went smoothly. (It took almost a week to find this solution!)

I'm familiar with promises and what they mean and they usage (I use it a lot in AngularJs whenever I receive any answer from the server using $promise). Is it possible to use something like promises here? I used this approach but again doesn't work (the answer is again an empty array):

    function getAll() {

    return new Promise(function (resolve, reject) {
        var images = [];
        db.collection('fs.files').find({}).toArray(function (err, files) {
            var Files = files;
            for (var i = 0; i < Files.length; i++) {
                getFileById(Files[i]._id, function (err, img) {
                    if (err) {
                        reject('error occurred');
                    }
                    else images.push(img);
                })
            }
        });
        resolve(images);
    });
}

As I mentioned in this post, I successfully handled this issue with setTimeout but I think this way of handling is totally wrong since I don't know when the retrieval process is finished (here I choose 1 sec delay but in general you never know).

What is the best way to handle these kinds of behavior as they are so common?

Kasra GH
  • 157
  • 2
  • 5
  • 22
  • Just put the `callback(null, images)` into the body of `db.collection`. You don't need the `setTimeout` in there – Stephan Strate Sep 02 '17 at 12:40
  • Did you [look at the documentation](http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#find)? It's usually a good place to start, and since it's got plenty of examples of async handling with and without promises then you should not even need to ask the question. Not sure what you read that said to use `setTimeout()` but the sooner you forget that the better off you will be. – Neil Lunn Sep 02 '17 at 12:42
  • I've tried it, but it didn't work. I even put in different places like inside the **for loop** (which is ridiculous) but again it didn't work. It works on;y when I used the setTimeout function. – Kasra GH Sep 02 '17 at 12:44
  • Response to @Neil Lunn: Honestly my problem is not MongoDB at all. It works properly throughout my project. My problem is how to handle these kinds of behavior. The same thing can happen when you want to simply read a file from your system using FS. – Kasra GH Sep 02 '17 at 12:46
  • Yeah see I'm just going to point you at the general resources already here, Because despite your statement, your coding here ( and further comments ) indicates that you don't appear to understand promises or callbacks very well. So those places are where you need to look and get reading and practicing. – Neil Lunn Sep 02 '17 at 12:53

0 Answers0