canjs/can-set

`set.has` does not work well with pagination

Closed this issue · 3 comments

Having algebra with offsetLimit the has method does not recognize a new item as a part of the paginated set:

const algebra = new canSet.Algebra(
  canSet.props.offsetLimit('$skip', '$limit')
)
const set = { $limit: 5, $skip: 0 }
const props = { name: "My Portfolio" }
const has = algebra.has(set, props)
// -> false

This peculiarity eliminates an updated item with can-connect real-time behavior from the live list:

const portfolios = Portfolio.getList({$limit: 5, $skip: 0})
...
portfolios[0].name = "My portfolio 2"
portfolios[0].save()
...
// -> portfolios will not contain the updated instance after receiving an updated event 
// from server by the real-time behavior.

@ilyavf wouldn't the change to ignore pagination during .has potentially cause new instances to incorrectly appear on multiple pages?

e.g you have two different widgets showing different pages of some real-time enabled type, a third widget creates (and saves) a new instance of that type. .has would return true for the sets shown by both pages, resulting in the new instance now appearing on both displayed pages.

Instead of ignoring pagination, I think .has needs to check if the id exists in the range defined by the pagination props, though I'm not sure how that would work with string or compound ids.

My issue #59 touches on a related id & pagination problem

After discussing this with Justin I believe this issue can be closed. There is no ideal generic solution for this problem and the best we can do going forward is document the behavior and allow users to implement an application specific solution for it if they desire. I'll open a new issue for that task.

#66 was created to document this behavior and a method of overriding it with an application specific implementation.