Reputation: 24789
I'm using MVC 4 with Breeze and Angular.
I have created some domain models and I only want to display a list of a model. This is my code:
ApiController:
[BreezeController]
public class TournamentApiController : ApiController
{
private EFContextProvider<TournamentContext> _contextProvider;
public TournamentApiController()
{
_contextProvider = new EFContextProvider<TournamentContext>();
}
[HttpGet]
public string Metadata()
{
return _contextProvider.Metadata();
}
[HttpGet]
public IQueryable<Tournament> Tournaments()
{
return _contextProvider.Context.Tournaments;
}
// ~/breeze/todos/SaveChanges
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
}
DataService.js:
/* dataservice: data access and model management layer */
app.dataservice = (function (breeze) {
breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);
var serviceName = '/breeze/TournamentApi'; // route to the same origin Web Api controller
// *** Cross origin service example ***
//var serviceName = 'http://todo.breezejs.com/breeze/todos'; // controller in different origin
var manager = new breeze.EntityManager(serviceName);
// manager.enableSaveQueuing(true);
var dataservice = {
getAllTournaments: getAllTournaments,
createTournament: createTournament,
saveChanges: saveChanges,
};
return dataservice;
/*** implementation details ***/
function getAllTournaments() {
var query = breeze.EntityQuery
.from("Tournaments");
return manager.executeQuery(query).then(getAllSucceeded);
}
function getAllSucceeded(data) {
debugger;
return data.results;
}
function createTournament(name) {
return manager.createEntity('Tournament', { Name: name });
}
function saveChanges() {
return manager.saveChanges().fail(fail);
}
function fail(error) {
console.log = error;
debugger;
}
})(breeze);
and my angular controller:
$scope.getAllTournaments = function () {
dataservice.getAllTournaments().then(getAllSucceeded);
}
function getAllSucceeded(data) {
debugger;
if (data.length > 0)
$scope.tournaments = data;
else
$scope.tournaments = [];
}
$scope.getAllTournaments();
In the client side I can see the 4 objects which are stored in the DB. The list, however, contains objects like this:
0: e.dataType
1: e.dataType
2: e.dataType
3: e.dataType
When I expand such an object I see this:
_backingStore: Object
entityAspect: o
__proto__: Object1
When I expand the _backingStore further, I see this:
Date: Mon Jan 01 1900 00:00:00 GMT+0100 (W. Europe Standard Time)
Id: 1
Name: "123"
And this is off course the thing I need.
I have the feeling I'm doing something wrong, because I think I shouldn't use e.dataType._backingStore
in my client code when I iterate the list.
What do I have to do to just call the property name instead of the whole path?
Upvotes: 0
Views: 1111
Reputation: 17863
You didn't say that your Angular app is failing nor that the bindings are failing nor that you are unable to get a value when you write aTournament.name
. That all works, yes?
It it doesn't, please tell us.
What I think you seek is an explanation for the values you see when you examine the entities in a debugger.
First, no, you should not be referencing the _backingstore
directly ... ever. The "_" in the name tells you that it's off limits.
Before I explain what's going on, I have to ask you about e.dataType._backingStore
. I've never seen e
; never seen e.dataType
. I can't reproduce it in any of the 4 debuggers I'm using (Chrome, IE10, FF, Visual Studio 2012). Please tell us which browser you are debugging in.. I have a feeling the answer will lie there.
But back to the story ...
It is true that these entities do look a little strange in the debuggers. They all display a property list more or less like this:
_backingStore: Object entityAspect: ctor __proto__: Object
Your entity properties have apparently disappeared. Where did they go? How can this possibly work? And yet it does! Evidently you've tried our Angular sample apps. They worked right? They showed the Todo description for example.
Yes, you will find them when you drill into _backingStore
. But Angular isn't doing that. And you shouldn't either
The answer to the mystery is that these Breeze entities are built with ECMA Script 5 "defined properties". Your entity properties are implemented as defined properties with getters and setters that have Breeze logic inside.
For some reason, the debuggers don't list the defined properties even though they are there. Although you won't see theaTournament.name
property in the list, you can read and set it just fine. That's what Angular is doing. And so should you.
The FireBug debugger (for FireFox) does a better job than most of revealing the defined properties. In this snapshot, I've selected the first entity and typed a period; FireBug reveals my choices which include the entity properties (e.g., Id, Description, ...).
The thing to remember is that your entity properties are really there and you can code with them in the expected manner. Don't let the debuggers fool you.
None of this holds if you are using an older browser (e.g, IE8). Older browsers do not support defined properties and Angular+Breeze will not work with them. If those browsers are really important to you and you'd like to use Breeze, please consider an alternative model library such as Knockout (see HotTowel for a full stack comparable to Angular+Breeze).
Upvotes: 2