Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

db.observe using {fields: {...}} doesn't function as it should #6

Open
Streemo opened this issue Aug 4, 2016 · 2 comments
Open

db.observe using {fields: {...}} doesn't function as it should #6

Streemo opened this issue Aug 4, 2016 · 2 comments

Comments

@Streemo
Copy link

Streemo commented Aug 4, 2016

<EDIT: Read this first

I can't think of a good solution to this problem ( without digging into your source ) other than observing the entire query and then manually applying a diffing layer before setState is reached.

The main point is that the version number captures changes in the entire document, which is useless if I only care about changes in a slice of the document.

I've been working on this library, but it's nowhere near complete. It tries to do things the Meteor way with scoping: data store which allows for scoped reactivity it'll work for the basics, but it's not anywhere close to ready.

/EDIT>

Possible design flaw?

Problem:

let obs = db.observe(function(){
  //this function is called even if someOtherField changes.
  return db.users.findOne({_id:someId}, {fields:{onlyThisField:1}})
})
obs.subscribe(function(res){
  //this function is not called if we specify `fields` in the .observe function above.
  //for example changing the value of onlyThisField will not trigger this function.
})

Bad Solution, not even a solution:

Unhappy fix:

let obs = db.observe(function(){
  //dont specify fields, which is a terrible, terrible solution :(
  //since the whole point was to specify fields for scoped reactivity...
  return db.users.findOne({_id:someId})
})
obs.subscribe(function(res){
  //this is called every time the entire doc changes anywhere,
  //even though we only care about onlyThisField.
})

Worse Solution, not even a solution:

Unhappy hack:

let obs = db.observe(function(){
  const user = db.users.findOne({_id:someId})
  //do stuff here with the changed obj.
})

Should this work?

This should not be necessary if specifying fields just worked.
This doesn't work, nevertheless, but perhaps it should?

let obs = db.observe(function(){
  const user = db.users.findOne({_id:someId})
  return user.email;
})
obs.subscribe(function(res){
  //only called if the version for user.email changed? 
  //only called if user.email !== the previous user.email?
})

This forces us to write our own diffing code. I thought this library took care of that! Is there a bug somewhere, perhaps, or did I misinterpret the goal of this library? Thanks.

@Streemo Streemo changed the title db.observe using {fields: {...}} db.observe using {fields: {...}} doesn't function as it should Aug 4, 2016
@Streemo
Copy link
Author

Streemo commented Aug 4, 2016

So, if you include _version: 1 in fields, then the updates work, but this solution does not actually scope the reactivity! It is equivalent to the "Bad Solution" above in that regard...

Another Bad Solution

let obs = db.observe(function(){
  //this gets called any time *anything* changes :(
  return db.users.findOne({_id:someId}, {fields: {onlyThisField: 1, _version:1}})
})
obs.subscribe(function(res){
  // at least this is called. onlyThisField may not have changed, yet this is still called.
  //even though we only care about onlyThisField.
})

One should definitely be able to scope the reactivity as I have shown by using fields. I don't think that API has been implmented in this library yet. Another thing: Meteor's minimongo has scoped reactivity implemented fully. It's very efficient.

In these docs:

// This will fire whenever the query needs to be updated. Note that this is fairly
// smart: it only processes change events it needs to, and if all document versions
// are the same since the last computation it's not recomputed.
todoItems.subscribe(function(results) {
  console.log('Author 1 TODO items:', results);
});

The query db.users.observe({_id: someId}, {fields:{onlyThisField:1}}) does NOT need to be updated unless onlyThisField has changed. In all of the examples above, this is not the case...

@Streemo
Copy link
Author

Streemo commented Aug 4, 2016

I can't think of a good solution to this problem ( without digging into your source ) other than observing the entire query and then manually applying a diffing layer before setState is reached.

The main point is that the version number captures changes in the entire document, which is useless if I only care about changes in a slice of the document.

I've been working on this library, but it's nowhere near complete. It tries to do things the Meteor way with scoping: data store which allows for scoped reactivity it'll work for the basics, but it's not anywhere close to ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant