JavaScript
Article

Write Better Queries with Breeze.js

By Taulant Spahiu

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?

Breeze.js is a JavaScript library that helps us manage data in rich client applications. Breeze runs natively in every browser and supports client-side querying, caching and dynamic object graphs.

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:

<script src="bower_components/breeze-client/build/breeze.debug.js"></script>

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 JavaScript component that performs AJAX requests
  • 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

The first thing to do is grab a copy of the Breeze JavaScript Client sample applications. The easiest way to do this is using Git:

git clone https://github.com/Breeze/breeze.js.samples.git

Within the project, navigate to node/zza-node-mongo folder:

cd breeze.js.samples/node/zza-node-mongo

Here you see three folders: client, database, server. In the database folder unzip zza-mongo-database.zip.

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 /var/lib/mongodb.

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 mongodb:nogroup:

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:

bower install

After the Bower components are installed, you need to navigate to the server folder /node/zza-node-mongo/server and install the Node modules:

npm install

Then, launch the app server from within the same folder:

node server.js

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.

zza app welcome screen

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);

The serviceName serves to find the service end-point and the route to the Web API controller.

Filters

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() (the 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));

Sorting

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

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 skip() and take().

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 .orderBy() with .skip() because this is required by many server-side data services.

var query = EntityQuery.from('Products')
    .orderBy('ProductName')
    .skip(5);

Projections

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 client folder.

client folder structure

These are the most important components:

  • index.html — most of this file is occupied with CSS and JavaScript file loading.
  • 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.

Inside of index.html, which is the door to the application, many CSS and JavaScript files are loaded. In the body of 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 client/app/services/dataservice.

Conclusion

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.

  • http://www.ferhatozal.com/ Ferhat Özal

    Great post :)

    • Taulant Spahiu

      Thanks, Ferhat :)

  • DGiG

    Is this based on John Papa’s ‘Code on the Beach’ presentation? Seems like he also has a Pizza app in his downloadable demo. github johnpapa/ng-demos

  • Karey Black

    This year I have made 72,000 dollars so far with my pc and I am a university student . I am linked with a business entity that outsource online jobs . I heard about it previous year and now I have made a great cash . It is very friendly to it’s users and I am just so happy to have that option …..

    www.yfuusa.da.cx
    ♣35

  • Ben

    But how the server understand this queries?

    • Taulant Spahiu

      Breeze and the server communicate with each other with the help of HTTP protocol and JSON. You don’t have to worry about the server side as long as it supports HTTP.

      • Ben

        So you say i don’t need to configure nothing on the server side?

  • Ben

    Node js and mongodb

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in JavaScript, once a week, for free.