Question

I've seen other questions that ask this, and I don't feel my issue is a duplicate of those.

Breezejs [Q] Unhandled rejection reasons (should be empty)

Unhandled rejection reasons (should be empty)

Okay so I've been following up on breezejs; following the documentation as close as possible as well as the samples, but I keep running into the same problem. The code I will present works in IE9+, and Chrome, but when I try it in IE7 and IE8, it blows up.

here is my server side controller (using webapi 2):

namespace Map.API.Controllers
{
    [BreezeController]
    public class LocationController : ApiController
    {
        readonly EFContextProvider<LocationEntities> _contextProvider =
            new EFContextProvider<LocationEntities>();

        [HttpGet]
        public string Metadata()
        {
            return _contextProvider.Metadata();
        }

        [HttpGet]
        public IQueryable<dbSTATES> States()
        {
            return _contextProvider.Context.MD_STATE_CD;
        }
    }
}

here is my angular factory:

mapapp.app.factory('StateContext', ['$http', 'StateModel', function ($http, StateModel) {
    configureBreeze();
    var dataService = new breeze.DataService({
        serviceName: "/Map.API/api/Location"
    });

    var datacontext = {
        getAllStates: getAllStates,
        getCachedStates: getCachedStates
    };
    return datacontext;

    /* BLOWS UP AFTER RUNNING MANAGER.EXECUTEQUERY(QUERY) */
    function getAllStates() {
        var query = breeze.EntityQuery
                .from("States");
        return manager.executeQuery(query);
    }

    function getCachedStates() {
        var query = breeze.EntityQuery
        .from("States").toType('MD_STATE_CD');
        return manager.executeQueryLocally(query);
    }

    function configureBreeze() {
        // configure to use webapi
        breeze.config.initializeAdapterInstances({ dataService: "webApi" });
    }
}

Here is how I'm calling it from my angular controller:

    StateContext.getAllStates().then(
        function (data) {
            var localData = data.results;  //never gets here
            logger.info("Fetched States");
        }).fail(function (e) { 
            logger.info(e);  //always gets here
        }).done();

Again, this works fine in modern browsers, but blows up in IE7 and IE8. After doing tons of research, no sources ever came up mentioning that this will fail. Even though BreezeJS documentation made mention of some things failing in IE7, there should be explicit info saying that this will never work.

If I happen to turn off metadata:

var dataService = new breeze.DataService({
    serviceName: "/Map.API/api/Location",
    hasServerMetadata: false
});

then this works in all browsers. But I would like to have the metadata turned on so that I can do caching. However, my big concern is that even if I get this fixed, I have NO idea if caching will still work in IE7.

Even though I love BreezeJS and it works phenominally with google chrome, I spent hours, days, weeks, and headaches making what I want work in IE7. Adding crazy amounts of browser supporting scripts, ie-shivs and ie-shims.. coming so close, then finding out localStorage isn't supported. I wish BreezeJS would document more about what isn't supported in IE7, I have a large portion of my customers that uses IE7 and IE8, and it's very tough to program things and finding out after hours that it just doesn't work.

Was it helpful?

Solution 2

Breeze + Angular does not work in IE8 or earlier. I am sorry it took you so long to discover that. I am also sorry that you are cursed with the need to support IE7 and IE8; that is a tough assignment.

We have been quite clear and upfront about this in our documentation from the very beginning. See, for example, the big blue notice box on the "Todo Angular Sample" and on the Breeze/Angular page.

A search of StackOverflow with the terms "breeze angular ie8" returns a January 2013 question and answer in which we state again, unequivocally, that the combination of Breeze and Angular does not work and will never work in IE8 or any browser that lacks support for ECMAScript 5 properties with getters and setters.

Did you know that the Angular team is also dropping its support for IE8 in all future releases in the 1.x version sequence? They say that it may work in IE8 but they will make no further attempts to ensure that it does ... nor will they bother testing to see if it does.

I should add that Breeze works fine with Knockout (and Durandal) in IE8 (and maybe IE7) although we too have stopped testing Breeze on IE8.

Finally, let me say that I am impressed you were able to make Breeze+Angular work with IE7 at all. I wish you the best in your efforts.

OTHER TIPS

I didn't mean to put the blame squarely on Breeze technology for my application. I realized late that it was also an angular thing. However, I have implemented the application in such away that Breeze + Angular works on IE7. Just have to turn off a few features.

(Deprecated way)
I've decided to "version" my javascript in a manner where i can detect older versions of IE and make accomadations:

Detect IE version in Javascript

So in my javascript code, I'd detect if an older IE browser is being used, and from there rewire how I'm fetching data; where if newer browsers are being used, I'd take advantages of BreezeJS + Angular.

(Useful advice)
It's a bit disappointing that it has come to this.

To gracefully handle querying, I've read a post (and talked to the author) about query/handlers pattern described here:

https://cuttingedge.it/blogs/steven/pivot/entry.php?id=92

For anyone who wants an angular-like framework with knockout (just to support older browsers), check out durandal: http://durandaljs.com/ (which seems to be gaining support for knockout and angular fans)

(Update - 08/11/2014 - I removed the logic mentioned about [if lt IE8] in the browser and handled through javascript in my controller. I also removed the caching ability on all browsers, server handling worked just fine with what was needed

Since angular doesn't support IE7 very well, I split up the code into two different pages, one called Home.html and HomeIE7.html. Although it is more maintenance, I think it's better than having two sets of logic in one html page. For any changes I made, I use a program called "Beyond Compare", which allows me to analyze both files and make sure the logic is the same between the two.

To switch between the two pages, this is what my starting Index.html looks like:

<!DOCTYPE html>

<div ng-app="mapapp" id="ng-app">
    <div ng-controller="LocationCtrl">
        <div ng-include="homeHTML" />
    </div>
</div>

and in your controller:

//templates to use - picks html to use, and doesn't use the ajax caching
$scope.homeHTML = !$('html').hasClass('msie7') ?
                        "Templates/Home.html?" + new Date().getTime() : 
                        "Templates/HomeIE7.html?" + new Date().getTime();

Remember, if you are using IE7, make sure in your service call from breeze that hasServerMetadata is turned off.

var dataService = new breeze.DataService({
    serviceName: serviceName,
    hasServerMetadata: false
});

As IE7 is incapable of making use of any extensible features of using server metadata. To know those extensible features, please click on the following: Breeze Metadata

With hasServerMetadata turned off, the response of your entities will look just like a regular javascript object. If it was turned on, and you don't use IE7, it would have been an entity object that you can cache and make queries against.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top