Juvaly
Juvaly

Reputation: 261

Render view only after async processing loop done

I need help with something very basic I can't seem to solve.

The code below loops over an input file, inserts rows into the database and renders a results view.

My problem is the view is rendered before all the database callbacks run, so it always seems like 0 rows were processed.

How can I render only after all callbacks have been called?

router.post('/upload', function(req, res) {
  var good_rows = 0;
  var bad_rows = 0;

  ... // get file data

  _.each(data, function(fileRow) {
      var dbRow = {
          data1: fileRow.data1,
          data2: fileRow.data2
      };

      // insert row to db
      model.create(dbRow, function(insertedCount) {
          // this callback is called only after the view was rendered :(
          if (insertedCount == 1) good_rows++;
          else bad_rows++;
      });
  });

  res.render('upload_result', {
      result: {
          good_rows: good_rows,
          bad_rows: bad_rows,
          log_location: '#'
       }
  });
});

Upvotes: 0

Views: 115

Answers (1)

prasun
prasun

Reputation: 7343

you need to check after each callback, that all operations are done

  _.each(data, function(fileRow) {
      var dbRow = {
          data1: fileRow.data1,
          data2: fileRow.data2
      };

      // insert row to db
      model.create(dbRow, function(insertedCount) {

          if (insertedCount == 1) good_rows++;
          else bad_rows++;
      //on each callback check if completed
      if(good_rows+bas_rows >= data.length)
         res.render('upload_result', {
            result: {
               good_rows: good_rows,
               bad_rows: bad_rows,
               log_location: '#'
            }
         });
      });
  });

Upvotes: 1

Related Questions