Write Better Queries with Breeze.js
This article was peer reviewed by Agbonghama Collins. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!
Data volumes are growing rapidly and they are becoming more complex to maintain. Many developers want to avoid the problems and headaches that are caused by data issues during their job.
One of the libraries that makes our job easier is Breeze.js. In this article, we will talk about how we can write better queries with Breeze.js. But firstly, we should know what is Breeze.js and why it was created.
What Is Breeze.js?
The best thing about Breeze.js is that it doesn’t mirror the server-side model, but it creates it dynamically. With Breeze, the cached data is on the client side. It doesn’t need to query the server because it can query the cache instead. It saves the cache locally and offline. When it is reconnected, it syncs the changes.
Two of the strongest points of Breeze.js are rich queries and change tracking. Four powerful ways to query are filters, sorting, paging and projections. A query needs help to execute, that’s where Breeze EntityManager comes in. Each entity keeps track of its own changed state. We will discuss this later.
Breeze.js works well with a lot of frameworks including AngularJS, Backbone.js, Knockout, Node.js and many others.
Now let’s look at how to setup the environment and get to coding.
How to Install
Breeze can be downloaded from its repository on GitHub. The most common versions of Breeze are:
- breeze.debug.js — This is the standard client library that I suggest using. It has support for third-party libraries including Backbone and Knockout.
- breeze.min.js — Breeze.min.js is the minified breeze.debug.js, its size is 175 KB compared to size of breeze.debug.js, which is 602 KB.
There are two other ways to get Breeze: through Bower and npm. I prefer using Bower because I am more familiar with it. Open the terminal, then go to the client directory and run these two commands to get Breeze:
bower install breeze-client bower install breeze-client-labs
In order to include Breeze into a the project, you should include this script tag inside the
<body> of your page:
Older browsers that do not support ECMAScript 5 can cause problems for Breeze. A shim library is necessary to enable ES5 syntax on these browsers. For Internet Explorer users, it is recommended to enter this code inside the
<head> tag, to avoid compatibility mode issues.
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"/>
Breeze also needs some extensions to work normally:
- a data service
- a model library for data binding (such as Knockout)
- a promise library
So as to demonstrate Breeze in action, in the next section I’m going to show you how to get one of Breeze’s sample applications up and running. This will include all of these things out of the box.
Prerequisites for the Sample App
So as to run the sample app, you will need Node.js and MongoDB installed on your machine.
Node.js is free to use, and can be downloaded from the project’s homepage. If you have Bower or npm on your computer, you also have Node installed. If you are having trouble installing Node, then check out our tutorial on npm (which includes a section on this): A Beginner’s Guide to npm
MongoDB can be downloaded from their download page. They have guides on how to install for all major operating systems.
Setting up the Sample App
git clone https://github.com/Breeze/breeze.js.samples.git
Within the project, navigate to
Here you see three folders:
server. In the
database folder unzip
cd database unzip zza-mongo-database.zip
Now we need to find out the name of the directory MongoDB uses to read and write its data. By default this is
/data/db on Linux and OS X and
\data\db on Windows. However, if you installed MongoDB using a package manager, check the
/etc/mongod.conf file provided by your packages to see the directory specified. For me (on Linux) it was
Now move the files to that directory:
sudo mv zza.0 zza.1 zza.ns /var/lib/mongodb/
And change the ownership of the files to
sudo chown mongodb:nogroup /var/lib/mongodb/zza.*
If the mongodb server isn’t running, start it while pointing to this database directory:
sudo service mongod start
Back in the client folder
/node/zza-node-mongo/client install Bower packages:
After the Bower components are installed, you need to navigate to the server folder
/node/zza-node-mongo/server and install the Node modules:
Then, launch the app server from within the same folder:
The final step is to open the browser and navigate to http://localhost:3000. If you see the figure below, you have followed all the right steps. If not, go back through the steps above to ensure you have done everything correctly, and consult this page for more information.
Write Better Queries
Before we examine the CRUD app architecture, it’s good to learn about some of the Breeze components which helps us write better queries. The first thing to understand is the Breeze EntityManager. The EntityManager is the gateway to the persistence service and holds a cache of entities that the application is working with. These include entities that have been queried, added, updated, and marked for deletion.
var serviceName = 'breeze/todos'; var manager = new breeze.EntityManager(serviceName);
serviceName serves to find the service end-point and the route to the Web API controller.
Writing queries with Breeze is very simple and straightforward. For example, look at this query which shows orders placed after February 1, 2010.
var query = EntityQuery.from('Orders') .where('OrderDate', '>', new Date(2010, 1, 1))
Another good way to write queries with Breeze is through compound conditions with predicates. The predicate is a condition that is true or false. Let’s combine two predicates with
AND operator) to create an expression that is true for both conditions.
In the sample below the first predicate selects all pizzas that cost more than 60 dollars. The second one selects all orders which were placed after January 15, 2015. When they are combined with
.and() , they create a query which selects all pizzas that cost more than 60 dollars and were ordered after January 15, 2015.
var q1 = new Predicate('Pizza', '>;', 60); var q2 = new Predicate('OrderDate', '>', new Date(2015, 0, 15)); var query = baseQuery.where(q1.and(q2));
Another type of query is sorting. Breeze code for sorting products in descending name order is shown below. Its code is very readable.
var query = EntityQuery.from('Products') .orderBy('ProductName desc');
Breeze has three types of sorting. These are single property sort, multiple property sort, and related property sort.
Paging is the process of returning the results of a query in smaller subsets of data or, in other words, pages. Paging in Breeze can be done in two ways, with
In order to get the first five products which start with letter “E”, we could do the following:
var query = EntityQuery.from('Products') .where('ProductName', 'startsWith', 'E') .take(5)
Skip is used when you don’t want to take a specified number of objects, but rather returns the remainder of them. The code below skips the first five products and return the rest. It is necessary to use
.skip() because this is required by many server-side data services.
var query = EntityQuery.from('Products') .orderBy('ProductName') .skip(5);
Projection queries allow you to query for exactly those properties of an entity that you actually need. Let’s see an example showing a simple projection in Breeze which returns the names of customers beginning with the letter “C”.
var query = EntityQuery.from('Customers') .where('CompanyName', 'startsWith', 'C') .select('CompanyName');
There are four types of property projections: single data, single navigation, multiple property and related property projections.
If you want more information about Breeze queries you can consult their extensive documentation.
Simple App Architecture
Now let’s turn back to the app that we had up and running in the previous section (if all went well, it should still be available at http://localhost:3000).
Zza! is a CRUD app for ordering pizzas, salads, and drinks. It uses the BMEAN stack (which stands for Breeze + MEAN).
As we saw previously, the part of the app we are interested in (
breeze.js.samples/node/zza-node-mongo) contains folders representing the client, server and database. The
database folder contains the database (as the name implies). The
server folder contains the relevant Node and Express files. Now let’s focus on the client side and see what’s in the
These are the most important components:
app— this folder contains the AngularJS application module, its directives, services and views.
bower— inside this folder, you can find all of components which we installed on the client side through command-line.
css— here all of the app’s stylesheets are located.
images— the images and glyphicons for the app can be found in this folder.
index.html there is a bit of layout, but mostly
<script> tags that lead to Angular components, application scripts, controllers and services.
<body class="ng-cloak" data-ng-app="app"> <!-- Shell of the Sample App --> <div data-ui-view="header"></div> <div id="shell-content" data-ui-view="content"></div> <div data-ui-view="footer"></div> <!-- Vendor Scripts --> ... <!-- Application scripts --> <script src="app/app.js"></script> <!-- must load first --> <script src="app/appStart.js"></script> <!-- Feature Areas: controllers --> ... <!-- Directives & Routing --> ... <!-- Services --> <script src="app/services/config.js"></script> ... </body>
AngularJS is the muscle of the application. It dynamically loads templated views, as well as the header and footer. You may notice three
div tags, each with a
data-ui-view attribute. It is here that the templated views are loaded. Most of the application activity happens inside the
div tag with the id
shell-content. This shows the orders page, the products page and most of what we see.
Breeze controls all the application’s data actions and movements. The Breeze
EntityManager is focused on queries, caching, change-tracking, validating, and saving entity data. In this application, controllers make data requests through
dataservice, which can be found at
In this article we discussed Breeze.js, its features and some example queries to demonstrate how Breeze simplifies our job as developers. Hopefully you now have an idea of how to set up Breeze and understand the architecture of a sample app.
Breeze is a good tool to use because it decreases the amount of code we need to write, thus saving us time and making us more productive. If you guys are dealing with lots of data on your projects, I highly suggest learning Breeze. I’d love to hear your thoughts about Breeze.js in the comments below.