mondora / asteroid

An alternative client for a Meteor backend
MIT License
734 stars 101 forks source link

behavior of reactiveQuery and collections in example #49

Open aegor opened 9 years ago

aegor commented 9 years ago
// Connect to a Meteor backend
var ceres = new Asteroid("localhost:3000");

// Use real-time collections
ceres.subscribe("tasksPublication");
var tasks = ceres.getCollection("tasks");

tasks already contains values in tasks._set._items internal object

tasks.insert({
  description: "Do the laundry"
});
// Get the task
var laundryTaskRQ = tasks.reactiveQuery({description: "Do the laundry"});
// Log the array of results
console.log(laundryTaskRQ.result);

laundryTaskRQ.result in this (pseudo-synchronous) case is always empty array

// Listen for changes
laundryTaskRQ.on("change", function () {
  console.log(laundryTaskRQ.result);

In this case, result contain actual values.

});

My questions:

  1. Does reactiveQuery have synchronous behavior in this example? Or your example incorrect?
  2. if (1) is true, does Collection have API methods to get actual values in already existed ._set._items ?
pscanf commented 9 years ago

Hello there,

The answer to question #1 is: yes and no :-) . reactiveQuery is synchronous the first time it's run, meaning that if you have documents in your collection, reactiveQuery will synchronously get them. After that first run, each time a change occurs in the collection, the query will (partially) re-run, emitting (if needed) the change event. But the example is indeed a bit misleading, since right after you've subscribed to the tasksPublication you have likely not received any document yet, therefore laundryTaskRQ.result will be empty. It'll gradually fill as documents get sent by the server (and ofc each time a change occurs, the change event will be fired).

The answer to #2 is therefore: yes, reactiveQuery can do that (just pass it an empty selector).

Hope this clarifies things. :-) Let me know if you need further help.

Cheers

aegor commented 9 years ago

Ok, i found problem. Because subscriptions has promises in .ready property, Asteroid initialize sequense MUST conttain resolution for this, for example:

var ra = new Asteroid("localhost:3000");
    var plSub = ra.subscribe("players");
    var deSub = ra.subscribe("designs");

    var subs = Q.all([plSub.ready, deSub.ready]);
    subs
        .then(function(result) {
            console.log("then", result);
            var players = ra.getCollection("players");
            var designs = ra.getCollection("designs");
            var pl = players.reactiveQuery({
                name: "pl1"
            });
            console.log("pl:", pl.result);
            return result;
        })
        .fail(function(fail) {
            console.log("ERROR:", fail);
            return fail
        })
        .done();

This is the only reliable way to initialize Asteroid subs. Asteroid Subscriptions is not synchronous, as example in README.md

jariwalabhavesh commented 8 years ago

Each time any changes occur in collection then it is returning whole dataset.

Can it be possible to get only updated or inserted document in change event?

Any one has idea about that?