Search code examples
breeze

breezejs: inlineCount when using FetchStrategy.FromLocalCache


Would it make sense to add inlineCount to the resultset when the data comes from the cache instead of the server ?

I store the count locally, so as long as don't leave the current url (I use angularjs), I can get it from a variable in my controller. But once I've left that url, if I go back to it, the data will still come from the cache, but my local variable is reset to initial value.


Solution

  • Update 12 March 2015

    The requisite changes have been committed and should make the next release (after 1.5.3).

    Of course the inlineCount is only available in async query execution.

    The synchronous em.executeQueryLocally(query) returns immediately with the paged result array; there's no place to hold the inlineCount.

    Here's an excerpt from the new, corresponding test in DocCode.queryTests: "can page queried customers in cache with inline count"

      var query = EntityQuery.from('Customers')
          .where('CompanyName', 'startsWith', 'A')
          .orderBy('CompanyName')
          .skip(2).take(2)
          .inlineCount()
          .using(breeze.FetchStrategy.FromLocalCache);
    
      return em.executeQuery(query)
               .then(localQuerySucceeded);
    
      function localQuerySucceeded(data) {
        var custs = data.results;
        var count = custs.length;
        equal(count, 2,
            "have full page of cached 'A' customers now; count = " + count);
    
        var inlineCount = data.inlineCount;
        ok(inlineCount && inlineCount > 2,
          'have inlineCount=' + inlineCount + ' which is greater than page size');
      }
    

    Update 9 May 2014

    After more reflection, I've decided that you all are right and I have been wrong. I have entered feature request #2267 in our internal tracking system. No promise as to when we'll get it done (soon I trust); stay on us.

    Original

    I don't think it makes sense to support inlineCount for cache queries because Breeze can't calculate that value.

    Walk this through with me. You issue a paged query to the server with the inline count and a page size of 5 items.

    // Get the first 5 Products beginning with 'C'
    // and also get the total of all products beginning with 'C'
    var query = EntityQuery.from("Products")
        .where("ProductName", "startsWith", "C")
        .take(5)
        .inlineCount()
        .using(manager);
    

    Suppose you run this once and the server reports that there are 142 'C' customers in the database.

    Ok now take that same query and execute it locally:

    query.using(FetchStrategy.FromLocalCache).execute().then(...).fail(...);
    

    How is Breeze supposed to know the count? It only has 5 entities in cache. How can it know that there are 142 'C' customers in the database? It can't.

    I think you're best option is to check the returned data object to see if it has an inlineCount value. Only reset your bound copy of the count if the query went remote.