Breeze.js:

Rich Data Management for the JavaScript Client

Client-side querying, caching, dynamic object graphs, change tracking and notification, model validation, batch save, offline ... all part of rich data management with Breeze.js running natively on every browser (all 2.5 billion of them).

Breeze.js communicates with any remote service that speaks HTTP and JSON. Optional breeze server components make it easier to build services that support breeze client applications. Learn more about these technology opportunities:

ASP.NET  Java  Node MongoDB  Node Sequelize

More Information

Query like LINQ
Async with promises
Change tracking
Knockout data binding
Angular data binding
Query with related entities
Navigate to related entities
Flatten entity graphs
Query server or cache
Save changes offline
/* Query like LINQ */
// Define query for customers 
// starting with 'A', sorted by name,
var query = breeze.EntityQuery
           .from("Customers")
           .where("CompanyName", "startsWith", "A")
           .orderBy("CompanyName");

//... execute it later ...
/* Async query with promises */
// Execute query asynchronously on remote server
// returns a promise ... with success/fail callbacks
var promise = manager.executeQuery(query)
              .then(querySucceeded)
              .fail(queryFailed);

/* Async save with promises */ 
// Batch asynchronous save of all entities w/ pending changes 
// returns a promise ... with success/fail callbacks 
var promise = manager.saveChanges()
              .then(saveSucceeded) 
              .fail(saveFailed);
/* Change tracking */
// save all changes (if there are any)
if (manager.hasChanges()) {
    manager.saveChanges().then(saveSucceeded).fail(saveFailed);
}
 
// listen for any change to a customer
customer.entityAspect.propertyChanged.subscribe(somethingHappened); 
 
// listen for validation errors
customer.entityAspect.validationErrorsChanged.subscribe(updateValidationUI);
<!-- Knockout template -->
<ul data-bind="foreach: results">
  <li>
    <span data-bind="text:FirstName"></span>
    <span data-bind="text:LastName"></span>
  </li>
</ul>

// bound to employees from query
manager.executeQuery(breeze.EntityQuery.from("Employees"))
       .then(function(data){ ko.applyBindings(data);} );
<!-- Angular template -->
<li data-ng-repeat="emp in employees">
    <label>{{emp.FirstName}}</label>
    <label>{{emp.LastName}}</label>
</li>

// bound to employees from query
manager.executeQuery(breeze.EntityQuery.from("Employees"))
       .then(function(data) { $scope.employees = data.results; });
/* Query with related entities using expand */
// query for orders of customers whose name begins "Alfreds"
// include their customers & child details & their detail products
breeze.EntityQuery.from("Orders")
   .where("Customer.CompanyName", "startsWith", "Alfreds")
   .expand("Customer, OrderDetails.Product")
   .using(manager)
   .execute().then(querySucceeded).fail(queryFailed);
/* Navigate to related entities in cache */
// Query success callback
function querySucceeded (data) {
    var order1 = data.results[0];
    // Parent customer of the order
    var customer = order1.Customer();  
    // Product of the first OrderDetail of the order
    var product1 = order1.OrderDetails()[0].Product();
}
/* Flatten entity graphs */
// Projection query: "select" flattens the Orders to 4 fields.
// Order id, ship date, & customer name of Orders w/ freight > $500
breeze.EntityQuery.from("Orders")
   .where("Freight", ">", 500)
   .select("OrderId, Customer.CompanyName, ShippedDate")
   .orderBy("Customer.CompanyName, ShippedDate");
/* Query the server, cache, or both */
var query = breeze.EntityQuery("Customers");

// execute query asynchronously on the server
manager.executeQuery(query).then(querySuccess).fail(queryFail);

// execute query synchronously on local cache
var customers = manager.executeQueryLocally(query)
 
// fetch customer by id from cache (if found) or remotely
var checkCacheFirst = true;
manager.fetchEntityByKey("CompanyName", 42, checkCacheFirst) 
       .then(fetchSuccess).fail(fetchFail);
/* Save changes offline; restore later */
var changes = manager.getChanges();
var exportData = manager.exportEntities(changes);
 
window.localStorage.setItem("changes", exportData);
 
// ... later ...
 
var importData = window.localStorage.getItem("changes");
manager.importEntities(importData);

Breeze Todo

Todo demonstrates Breeze's ability to query; create, modify, and delete entities; validate, and save.