1

I'm trying to integrate Baconjs into my current Nodejs project, in this project I used Async https://github.com/caolan/async to handle callbacks. One of the methods is async.waterfall that is now I want to port it to Bacon, using Bacon.fromNodeCallback(...). My code in NodeJS:

async.waterfall([
  function findCondition(callback) {
    conditionBoundary.findById(condition.id, callback);
  },

  function updateCondition(loadedCondition, callback) {
     if(loadedCondition) {
      condition.created = loadedCondition.created;

      conditionBoundary.updateCondition(condition, function(error, numberOfDocs) {
        if(error) {
          return callback(error);
        }

        if(loadedCondition.prettyUrl && loadedCondition.prettyUrl !== condition.prettyUrl) {
          return callback(null, true, loadedCondition);
        }

        callback(null, false, null);
      });
    }
  },

  function updateLinkInConditionDescription(isUpdated, loadedCondition, callback) {
    if(isUpdated) {

      conditionBoundary.findByPrettyUrlInDescription(loadedCondition.prettyUrl, function(error, docs) {
        if(error) {
          return callback(null, false);
        }

        async.each(docs, function(doc, eachCallback) {
          var desc = doc.vietnamese.description;
          desc = desc.replace(new RegExp(loadedCondition.prettyUrl, "gmi"), condition.prettyUrl);

          conditionBoundary.updateVietnameseDescription(doc.id, desc, eachCallback);
        }, function(error) {
          callback(null, false);
        });
      });
    } else {
      return callback(null, true);
    }
  }
], function(error, result) {
  if(error) {
    return done(false, util.error("Failed to update condition")("system"));
  }

  done(true, { message: "Condition has been updated" });
});

So I did it this way:

var result1 = Bacon.fromNodeCallback(fn, params...);
result1.onValue(function(val) {
  // perform some logic

  var result2 = Bacon.fromNodeCallback(fn2, params...);
  result2.onValue(function(val)) { .... }

  // and so on...
});

I feel like Im not doing it right. So what is the right way the accomplish this? I just get my head around with Bacon so any help can be really appreciated. Thanks!

dee
  • 23
  • 3

1 Answers1

0

Well, I finally solve my own problem after googling and reading this article http://abesto.net/bacon-js-on-the-server/. It makes me think about my problem and what I need to do with Bacon to archive the goal, rather then focus on converting async.waterfall method to Bacon. So I post my code here, hope that someone finds it useful:

var oldConditionStream = Bacon.fromNodeCallback(conditionBoundary,
                                                "findById",
                                                info.id).flatMap(function(oldCondition) {
  if(oldCondition) {
    return Bacon.once(oldCondition);
  } else {
    return Bacon.once(new Bacon.Error("fail"));
  }
});

oldConditionStream.onError(function(error) {
  return done(false, { message: "Failed to update condition" });
});

var updatingStream = oldConditionStream.flatMap(function(oldCondition) {
  condition.created = util.parseDate(oldCondition.created, "YYYY-MM-DD h:mm:ss a");

  return Bacon.fromNodeCallback(conditionBoundary, "updateCondition", condition).flatMap(function(nod) {
    if(!nod) {
      return Bacon.once(new Bacon.Error("fail"));
    }

    return Bacon.once(oldCondition);
  });
});

updatingStream.onError(function(error) {
  return done(false, util.error("Failed to update condition")("system"));
});
var updatingDescriptionStream = updatingStream.flatMap(function(oldCondition) {
  if(!_.isEqual(oldCondition.prettyUrl, condition.prettyUrl)) {
    var findingStream = Bacon.fromNodeCallback(conditionBoundary,
                                                    "findByPrettyUrlInDescription",
                                                    oldCondition.prettyUrl).flatMap(Bacon.fromArray);
    var anotherStream = findingStream.flatMap(function(cond) {
      var desc = cond.vietnamese.description;
      desc = desc.replace(new RegExp(oldCondition.prettyUrl, "gmi"), condition.prettyUrl);
      return Bacon.fromNodeCallback(conditionBoundary, "updateVietnameseDescription", cond.id, desc).map(true);
    });

    anotherStream.onEnd(function() {
      return Bacon.once(true);
    });

  } else {
    return Bacon.once(true);
  }
});

updatingDescriptionStream.onValue(function(flag) {
  return done(true, { message: "Condition has been updated" });
});

Cheer!

dee
  • 23
  • 3