Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

Breeze Function Chaining Pitfall

0.00/5 (No votes)
24 May 2014CPOL2 min read 10.6K  
Breeze pitfall. Understanding entityQuery function changing.

Introduction

Breeze, are you using it? No? Well, you should look into it. I won't say it's the best thing since sliced bread, because it isn't (yet). But if you are making HTML5 webapps with oData/wcf services to back them, you should be interested.

I like breeze, but still I had an issue with it, that's simple to explain, but hard to figure out.

The Problem

I will not explain what Breeze is. Cause if you aren't using it, you can skip reading this. But I encountered a mystifying problem using Breeze, which is rather easy to explain. If you know how Breeze's function chaining works.

Let's say you have the following code:

JavaScript
var query=new breeze.entityQuery().from("Customers").expand("Orders"); 

manager.executeQuery(query).then( function(returndata) { .... 

That's a fantastic query. It will ask your oData webservice for all the customers, and their orders. It will create something like http://<webservice-endpoint>/Customers/?$expand=Orders.

In my app, I had the issue that I couldn't just ask to expand all the possible relational properties of Customers. There were just too many. I decided I had to write some wrapper function and depending on where the user was, decide what things to expand. In the end, I wanted to wrap the expand functionality of Breeze in an if then statement.

JavaScript
var query=new breeze.entityQuery().from("Customers");
if(someInputVar) { 
      query.expand("Orders"); 
}

To my surprise, this did not expand the orders. Looking at the http stream, I did not see, $expand=Orders.

Why not?

Well, I know why now. I don't agree with the makers on why they did it this way, but at least I know. If you try to make proper function chaining, you will most likely return the instance of the object from within your function. Something like:

JavaScript
myfancyobject.prototype.doSomethingAwesome=function() { 
    this.doAwesome();
    return this;
}

This way, you can keep changing your functions and you can break up the chaining if you like. To use an if then else for example.

The builders of Breeze decided that this would be nonsense. Or I don't get the design reason because I'm not smart enough.

They decided that the function chain should not return this. But a clone of this. Their return looks something like:

JavaScript
myfancyobject.prototype.doSomethingAwesome=function() { 
    this.doAwesome();
    return clone(this);
}

So when you do query.expand, you are not changing the query object. The expand function will return new instance of entityQuery.

It took me forever to find this out. And when I did I was like WTF? I still don't get the reason behind this design, but I can easily fix my faulty query!!!

JavaScript
var query=new breeze.entityQuery().from("Customers");
if(someInputVar) { 
     //reassign query!! 
     query=query.expand("Orders"); 
}

Just reassign the query variable with the returning clone!

I had to read the code of Breeze itself to find out how to solve this simple problem. And I'm sharing it here, because it's really hard to figure out if you run into it.

History

  • 24-5-2014: Created tip

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)