3

I am using the Vogels library to interact with DynamoDb. AModel below is a model I have defined using vogels.define() and here is a snippet of code that I can not get working:

var Promise = require('bluebird')
Promise.promisifyAll(AModel);

var query = AModel
            .query(1)
            .usingIndex('a-index')

Promise.resolve(query.exec()).then(
function(output) {
    console.log(output)
})

output is:

{
  "_readableState": {
    "highWaterMark": 16384,
    "buffer": [],
    "length": 0,
    "pipes": null,
    "pipesCount": 0,
    "flowing": false,
    "ended": false,
    "endEmitted": false,
    "reading": false,
    "calledRead": false,
    "sync": true,
    "needReadable": false,
    "emittedReadable": false,
    "readableListening": false,
    "objectMode": true,
    "defaultEncoding": "utf8",
    "ranOut": false,
    "awaitDrain": 0,
    "readingMore": false,
    "decoder": null,
    "encoding": null
  },
  "readable": true,
  "domain": null,
  "_events": {},
  "_maxListeners": 10
}

How do I turn query.exec() into a bluebird promise? With Q, I would just use

q.ninvoke(query, 'exec').
Seth
  • 10,198
  • 10
  • 45
  • 68
user3409889
  • 187
  • 2
  • 11
  • 1
    `promisifyAll` means that you are supposed to use `.execAsync()` – Bergi Mar 03 '15 at 12:25
  • @Bergi That will not work because BlueBird will add a function `queryAsync` to `AModel` but then I need to add `.usingIndex('a-index')` after the query. – user3409889 Mar 05 '15 at 06:07
  • What do you mean, "after the query"? Notice that I didn't say anything about a `.queryAsync()`, but the `exec` method (that normally takes the callback and now should return a promise). – Bergi Mar 05 '15 at 06:09
  • Yea I tried that too `AModel.query(1).usingIndex('a-index').execAsync()` but I got an error saying execAsync is not a valid method or something of that sort. – user3409889 Mar 06 '15 at 09:02
  • OK, what kind of object does `.query(1).usingIndex('a-index')` yield? Is it an `AModel`? If not, try to `promisifyAll` that kind of type as well – Bergi Mar 06 '15 at 13:39

2 Answers2

0

I'm the author the Vogels library. I don't have any experience with bluebird, but can hopefully help out. When running query.exec(), without a callback passed in, vogels will switch to streaming mode. It will return a stream to the caller and will only start reading from the database once a reader has attached to the stream. You can read more about it in the streaming section of the readme

With your bluebird example its invoking query.exec without a callback, and with the Q example the ninvoke is most likely invoking the query.exec with a callback. I would see if there is an equivalent to ninvoke with bluebird.

Ryan Fitzgerald
  • 819
  • 5
  • 6
  • 1
    Thanks, I missed the part about the streaming APIs. I just manually converted query.exec to a promise using the technique found [here](http://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises) – user3409889 Mar 05 '15 at 06:10
  • It's `Bluebird.fromCallback(cb => /*...*/)` – Louay Alakkad Mar 03 '16 at 18:29
0

Edit: I took a few minutes to publish an npm package vogels-promisified

This should promisify everything:

var Promise = require("bluebird");
var vogels = require("vogels");

Promise.promisifyAll(require('vogels/lib/table').prototype);
Promise.promisifyAll(require('vogels/lib/item').prototype);
Promise.promisifyAll(require('vogels/lib/query').prototype);
Promise.promisifyAll(require('vogels/lib/scan').prototype);
Promise.promisifyAll(require('vogels/lib/parallelScan').prototype);

var vogels_model = vogels.model;
vogels.model = function(name, model){
  if (model) { Promise.promisifyAll(model); }
  return vogels_model.apply(vogels, arguments);
};

Then you can do stuff like this:

AModel
  .query(1)
  .usingIndex('a-index')
  .execAsync()
  .then( ... )

See also Issue: Add promise support

Nate
  • 12,963
  • 4
  • 59
  • 80