Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Using Breeze JS to Consume ASP.NET Web API OData in an Angular JS Application

DZone's Guide to

Using Breeze JS to Consume ASP.NET Web API OData in an Angular JS Application

· Web Dev Zone
Free Resource

Should you build your own web experimentation solution? Download this whitepaper by Optimizely to find out.

In last post , we saw how Breeze JS  eases the job of querying OData services. It will be a lot of fun to use this great library with our favourite SPA framework, Angular JS . In this post, we will see how to hook up these two libraries to create data rich applications. 

As stated in previous post, Breeze required data.js for to understand OData conventions. All functions performing CRUD operations in Breeze return a Q  promise. Any changes made to properties of $scope inside then method of Q are not watched automatically by Angular, as Q is a non-angular component. To make the changes visible, we need to explicitly call $scope.$apply(). To avoid this difficulty, Breeze team created an extension to convert Q  to $q . Name of the extension is to$q , it can be found on GitHub . 

Following is the list of scripts to be included on the page: 

<script src="scripts/q.js"></script>
<script src="scripts/datajs-1.1.1.js"></script>
<script src="scripts/breeze.debug.js"></script>
<script src="scripts/angular.js"></script>
<script src="scripts/to$q.js"></script>

We don’t need jQuery  anymore as Breeze detects presence of Angular and configures its AJAX adapter to use $http . (Check release notes of Breeze 1.4.4 ) 


As both Angular and Breeze are JavaScript libraries, they can be easily used together. But we can’t enjoy the usage unless we follow the architectural constraints of Angular JS. The moment we include Breeze.js in an HTML page, the JS object “breeze” is available in the global scope. It can be used directly in any of the JavaScript components, Angular controllers and services are no exceptions. Best way to use an object in any Angular component is through Dependency Injection. Any global object can be made injectable by creating a value. 

var app=angular.module(‘myApp’, []);
app.value(‘breeze’, breeze);
app.service(‘breezeDataSvc’, function(breeze){
 //logic in the service
});

This makes the service more testable as the input objects can be easily faked in unit tests. As Breeze requires some initial setup, it is better to wrap all Breeze operations in a singleton service. Breeze has to be configured to work with OData service and use Angular’s AJAX API instead of jQuery. It is done by the following statement: 

breeze.config.initializeAdapterInstances({ dataService: "OData" });

Now all we need to do is instantiate an EntityManager and start querying. Following is the complete implementation of the service including a function that does a basic OData request: 

app.service('breezeDataSvc', function (breeze, $q) {
    breeze.config.initializeAdapterInstances({ dataService: "OData" });
            
    var manager = new breeze.EntityManager("/odata/");
    var entityQuery = new breeze.EntityQuery();
            
    this.basicCustomerQuery = function () {
        return manager.executeQuery(entityQuery.from("Customers").where("FirstName", "contains", "M")).to$q();
    };
});

Following is a simple controller that uses the above service and sets the obtained results to a property in scope: 

app.controller('SampleCtrl', function ($scope, breezeDataSvc) {
    function initialize() {
        breezeDataSvc.basicCustomerQuery().then(function (data) {
            $scope.customers = data.results;
        }, function (err) {
            alert(err.message);
        });
    };

    initialize();
});

Run this page on browser and see the behaviour. 

Happy coding!

Implementing an Experimentation Solution: Choosing whether to build or buy?

Topics:

Published at DZone with permission of Rabi (ravi) Kiran, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}