Francesco Z Francesco Z - 11 months ago 42
Node.js Question

Express & Nodejs : How to call 'next()' only after have created schemas

i'm build an event app, and in my 'Event' schema i've an array of 'Tag's schemas, so each event can have one or more tags.


var EventSchema = new Schema({
tags: [{
type: Schema.Types.ObjectId,
ref: 'Tag'

And Tag:

var TagSchema = new Schema({
type: String,
require: true
type: Number,
default: 0

When a user wants to create an event it sends a json to the /POST in the event middleware with all the information regarding the event and an array composed by

//json sent by client to server

Since two events can't have the same name, in a specific middleware i check if some users has already created the tag or we need to actually store one.

// add the tags
addTags(req, res, next) {
var myBody = req.body;
if (myBody.tags) {
const len = myBody.tags.length
if (len > 0) {
// we need to search and store a tag if is has not already created
for (let i = 0; i < len; i++) {
let currentTag = myBody.tags[i]
// find the currentTag in the DB
}, (err, find) =>{
if (err) return next(err)
// if we not find it
else if (!find) {
// create new one
let newTag = new Tag({
name: myBody.tags[i].name
utils.saveModel(newTag, next, (saved) => {
// store it back the ref
} else {
// store the ref
console.log('tags added!.');
} else {

My problem is, how can i call the 'next' only after i've checked all the tags? Is it possible? Thank you

Answer Source

You can use Promise.all to wait for an array of promises to be fulfilled.

Code is untested but should give you the outline of a Promise solution.

mongoose = require('mongoose');
mongoose.Promise = require('bluebird');

// Promise to add a new tag
function addTag(req, currentTag) {
  let newTag = new Tag({
    .then( (saved) => {
      // Store it back the ref
      return req.Event.tags.push(saved._id)

// Promise to find a tag or add it.
function findTagOrAdd(req, currentTag) {
  return Tag.findOne({ name:})
    .then( (find) => {
      if ( find ) return req.Event.tags.push(find._id);
      // Otherwise create new one
      return addTag(req, currentTag);

// Promise to add all tags.
function addTags(req, res, next) {
  var myBody = req.body;
  if ( ! myBody.tags ) return next();
  if ( ! Array.isArray(myBody.tags) ) return next();
  if ( myBody.tags.length <= 0 ) return next();

  // Promise to find the currentTag in the DB or add it.
  var promised_tags = [];
  myBody.tags.forEach( (currentTag) => {
    promised_tags.push( findTagOrAdd(req, currentTag) )

  // Wait for all the tags to be found or created. 
  return Promise.all(promised_tags)
    .then( (results) => {
      console.log('tags added!.', results);
      return next();