0

I am implementing a MVC framework in Dart. I am implementing the find method and I want it to return the documents from that query.

The problem is that find() doesn't wait that the operation is performed and we need to bind a function inside then().

 static find(model, [params]){
     Db db = new Db("mongodb://127.0.0.1/dart");
     var models = [];
     db.open().then((o){
         return db.collection(model).find(params).forEach((d){
         models.add(d);
         });
     });
     return models;
}

Right now the return from find() is []. Do you know any way of returning the documents properly?

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
André Freitas
  • 1,070
  • 1
  • 10
  • 13
  • Take a look at https://github.com/vadimtsushko/mongo_dart/blob/master/example/blog.dart – Vadim Tsushko Jun 10 '14 at 18:22
  • Well, that really doesn't solve my problem. I just want to get the documents return and not deciding on find what I am doing with every document. Please take a look in the Python Driver for example, about how simple is to do a find and then getting the documents just in time http://www.giantflyingsaucer.com/blog/?p=839 – André Freitas Jun 10 '14 at 19:44
  • 1
    when doing potentially long running calls like to a database, the execution is better when it is asynchronous, if you only want to continue after you have your data then you just put all your code in the `.then((_){/*in here*/}) callback for when the future completes. it's done like this so it doesnt lock up your program, if you do want to continue doing other stuff whilst the database is fetching data. – Daniel Robinson Jun 11 '14 at 09:54

2 Answers2

2
 static Future<List> find(model, [params]){
     Db db = new Db("mongodb://127.0.0.1/dart");
     var models = [];
     return db.open().then((o){
       db.collection(model).find(params).forEach((d){
         models.add(d);
       });
       return models;
     });
}

and use it like

find(model, [p1, p2, p3]).then((m) => ...);
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Hi! Thanks for the comment :) Well, that solves the problem but it isn't a clean solution. I just what that find() returns the documents. – André Freitas Jun 10 '14 at 19:41
  • 2
    You can't convert from async to sync execution in Dart. There are discussions and plans to add a Future.await() to allow just that. Until then (I expect several months up to more than a year), when you start async the chain of of execution stays async until it is finished. – Günter Zöchbauer Jun 10 '14 at 21:16
  • I couldn't understand your point, sorry. You arr saying that about mongo dart or Dart? Dart by default runs every line of code one after another. – André Freitas Jun 10 '14 at 22:38
  • That's about Dart. `db.open()` returns a `Future`. This means it is an async operation. Async operation get queued and the next statement is executed. Your `return models` is executed before `db.open()` returns. `db.open()` or some code in `db.open()` (where async operation starts) is not executed before the current chain of operations is finished. https://www.dartlang.org/docs/tutorials/futures/ – Günter Zöchbauer Jun 11 '14 at 03:54
  • 1
    Cursor.forEach returns a future (it's an async function), for safety you may wish to chain the return of models. Eg: db.collection(model).find(params).forEach((d) { models.add(d); }).then((_) => models); – Matt B Jun 12 '14 at 19:12
2

If synchronous API of your framework is absolute requirement for you, I'm afraid you are out of luck with mongo_dart. There is no way to build synchronous facade on top of asynchronous API and mongo_dart (or any other database driver in Dart AFAIK, see postgresql or sqljocky for example) is asynchronous.

Your experience with synchronous mongodb drivers in any other languages is not fully applicable here. Mongo_dart much more resemble mongodb driver for nodejs - asynchronous too. For nodejs async driver you too cannot get the result synchronously, see related questions:

Synchronous function calls for nodejs mongodb driver or What is the right way to make a synchronous MongoDB query in Node.js?

So I guess you should either embrace asynchronous code or return to python. Dart can do some things synchronously in the console applications but all the networking I believe is fully async here.

Community
  • 1
  • 1
Vadim Tsushko
  • 1,516
  • 9
  • 10
  • Thanks for the explanation. I am wondering, if Dart behaves like this, how it's possible to send the model data to the view... Definetly, it's a hard task trying to build a good MVC Framework for Dart. – André Freitas Jun 11 '14 at 14:43
  • If you indeed interested I would recommend to take a look at existing MVC (or any other MV*) frameworks in Dart. There are plenty of them - from https://github.com/PureMVC/puremvc-dart-multicore-framework to https://angulardart.org/ – Vadim Tsushko Jun 11 '14 at 19:25
  • I do not presume that frameworks in question are good by your standards. I just believe that they solved specific problem - how to send the model data to view - in asynchronous environment. – Vadim Tsushko Jun 11 '14 at 19:42