Breezejs, How to fetch metadata at start with shared EntityManager Breezejs, How to fetch metadata at start with shared EntityManager angularjs angularjs

Breezejs, How to fetch metadata at start with shared EntityManager


I see your problem.

When Angular invokes your factory function to create the DataContext service, it expects to get back immediately (synchronously) a DataContext object that is ready to use. But you are returning a promise to return that DataContext at some time in the future ... and Angular just isn't built for that.

I like the idea though. You might want to propose it to the Angular team :-).

So what you're trying here just won't work. You have to return a DataContext immediately. Until the metadata arrive, you have to either block the entire UI or block the specific functionality that relies on metadata (e.g., createUser). It's kind of like waiting for the DOM to settle down before manipulating it with jQuery.

This situation is not Angular specific. You face the same quandary in a Knockout app. The resolution is similar.

Start by exposing some kind of "whenReady" hook on the DataContext. A promise might be a good idea. Something like this:

function (breeze, Q, model, logger, $timeout) {    logger.log("creating datacontext");    ...    var readyDeferred = Q.defer(), whenReady = readyDeferred.promise;    var datacontext = {            whenReady: whenReady,            ...        };    initializeDatacontext();    return datacontext; // now Angular is happy because it has a datacontext    function initializeDatacontext() {        manager.fetchMetadata()               .then(function () {                   readyDeferred.resolve();                   // do success stuff;               })               .fail(function (error) {                   readyDeferred.reject(error);                   // do error stuff;               });    }    //Function definitions}

Elsewhere in the bootstrapping of your app, you tie into the datacontext.whenReady promise.

    // somewhere inside your main controller    $scope.isReady = false;    datacontext.whenReady.then(function() {           $scope.isReady = true;           $scope.$apply();       })    .fail(function() { alert("Uh oh!"); });    ...

Now bind the scope's isReady to the HTML such that you get the desired behavior. You could use it to block the entire UI or just seal off functionality (e.g, "Create User") until the datacontext is ready.

Pleae don't use this pseudo-code literally. Use it for inspiration.