Breezejs - Metadata import error on IE8 - breeze

I have been running a project using Breezejs for a few months now, and everything was working quite fine up to when I updated to latest version ("1.4.5") and metadata import stopped working on IE8.
I was previously working with version "1.3.6" and it was running ok in IE8 (I have added es5-shims and json2 libraries as suggested, for "legacy" browser support).
Since I upgraded to latest version, however, when initializing a new entity manager and issuing the first query it returns the following error:
Unable to either parse or import metadata: [Object expected]
in the ctor.prototype.fetchMetadata method.
Tracing down the issue, I've come to understand that it fails running getES5PropDescriptor method on client-side added properties for entities extended with custom constructors (as specified on Breeze documentation here):
function getES5PropDescriptor(proto, propName) {
if (proto.hasOwnProperty(propName)) {
//next line throws the error!!!
return Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(proto, propName);
} else {
var nextProto = Object.getPrototypeOf(proto);
return nextProto ? getES5PropDescriptor(nextProto, propName) : null;
}
}
Is this a known issue in Breezejs? Any hint about how to make it work again on IE8 with latest Breezejs version?
I've also tried following suggestion from this post (basically commenting out invocation of isolateES5Props method), but to no avail.
Many thanks in advance for your precious support!

Update:
This has been fixed as of Breeze 1.4.7, available now.
Previous Post:
This is a bug. It will be fixed in the next version. A fix will also be checked into GitHub later today (just pull the breeze.xxx.js files). For now you can modify breeze.debug.js by adding the following function.
function canIsolateES5Props() {
try {
return Object.getPrototypeOf && Object.defineProperty({}, 'x', {});
} catch (e) {
return false;
}
}
and calling it at the top of the getES5PropDescriptor function.
function getES5PropDescriptor(proto, propName) {
if (!canIsolateES5Props()) return null;
...
// code from above
}

Related

Xamarin Forms - iOS not processing correctly

I am using the CrossDownManager plugin for Xamarin Forms
Here
When I run the method on Android it processes as expected. On iOS Debug.Writeline("Success!") isn't being hit like it was on Android.
Here is the code:
void ViewImage(string imageLink)
{
var downloadManager = CrossDownloadManager.Current;
downloadManager.PathNameForDownloadedFile = new System.Func<IDownloadFile, string>(file =>
{
string path = DependencyService.Get<IImageSaver>().Save("YHTS" + DateTime.Today.Ticks.ToString() + ".jpg");
Debug.WriteLine("Success!");
return path;
});
try
{
var file = downloadManager.CreateDownloadFile(imageLink);
Debug.WriteLine("file created");
downloadManager.Start(file);
Debug.WriteLine("downloadstarted");
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
}
For the life of me I can't figure out why the that code block isn't processed. Any ideas?
This is an interesting issue as technically your code should work as expected. I've done a little digging and found a reply to a similar question here.
your options are many... including:
DEBUG preprocessor as you show in your question.
Use System.Diagnostic.Debug.WriteLine: Any calls to Debug.* will be
removed by the compiler due to the [Conditional("DEBUG")] attribute
being applied.
Create your own "Logger" class as a wrapper to the stdout writers and
[Conditional("DEBUG")] it
Use Fody and re-weave the assemblies to remove/NOP/redirect the
WriteLine I do this to redirect the calls to in internal log and upon
crash or user stat requests, forward this log to our crash reporting
servers. etc, .....
So there are a few alternatives to consider, one of the common suggestions I've seen is to use the fully qualified reference for WriteLine(); as such:
System.Console.WriteLine("woop woop");
I would suggest giving the above a try first.

Program has stopped working. Breaking on exception: Class '_LocalLibraryMirror' has no instance getter 'classes'

This code does not work anymore.
String getHomePath() {
var home = Platform.environment['HOME'];
if(home != null) {
return pathos.normalize(home);
} else {
return null;
}
}
Breaking on exception: Class '_LocalLibraryMirror'
has no instance getter 'classes'.
Does this mean that the library "dart: mirrors" redesigned and the package "pathos" does not account for these changes?
Also, I'm surprised that package "pathos" uses "dart: mirrors" to determine in which environment it used (browser or standalone).
Here is the same problem mentioned https://github.com/angular/angular.dart/pull/408
Update to 1.1.0-dev.5.6 solved it for them.
You could check with pub upgrade if there is any updated package version that is not pulled due to version constraints and use dependency_overrides to force the newest package version.

Possible bug in getValidationMessages

I've created a custom entity level validation function, very similar to the one in the documentation (http://www.breezejs.com/documentation/validation). When I call getValidationErrors(), I get the following error:
Cannot read property 'name' of undefined
The error is coming from:
proto.getValidationErrors = function (property) {
assertParam(property, "property").isOptional().isEntityProperty().or().isString().check();
var result = __getOwnPropertyValues(this._validationErrors);
if (property) {
var propertyName = typeof (property) === 'string' ? property : property.name;
result = result.filter(function (ve) {
**return (ve.property.name === propertyName);**
});
}
return result;
};
There is no 'property' field in the custom entity level validator context. I'm using Breeze 1.4.5. Is this a bug? It seems to me the code above should check for 've.property', before trying to access the name.
Update
This has been fixed as of Breeze 1.4.7, available now.
Previous Post:
This is a bug that has already been fixed on GitHub and will be part of the next release (Breeze 1.4.7) out sometime next week. Or you can pull the breeze.xxx.js file from GitHub now if you need the fix earlier.

What is the proper syntax to chain multiple queries together?

I'm using the HotTowel SPA template which makes use of Durandal. In my Durandal ViewModels I am using Breeze to get some data from the database.
I have a datacontext class that I put all my breeze queries in and the queries all follow the pattern like the following:
getAthletes: function (queryCompleted) {
var query = breeze.EntityQuery.from("Athletes");
return manager
.executeQuery(query)
.then(queryCompleted)
.fail(queryFailed)
}
Since I'm doing an asynchronous call in the activate method of the view model, I have to return the promise that comes back from these calls in the activate method.
Using a single query works great like this:
function activate() {
datacontext.getAthlete(loadAthlete);
}
However, if I need to perform two queries I run into problems, but only in the release version of my application. I have tried doing this with the following syntax:
function activate() {
datacontext.getAthlete(loadAthlete).then(datacontext.getOtherData(loadOtherData));
}
This will work fine in debug mode, but when I deploy it out to the server and my scripts get bundled, I get an exception which isn't very clear.
t is not a function
I've also tried chaining them together in my datacontext class like below, but I still get the same error.
getAthleteAndEfforts: function (athleteId, athleteQueryCompleted, effortsQueryCompleted) {
var athleteQuery = breeze.EntityQuery.from("Athletes").where("id", "==", athleteId);
var effortsQuery = breeze.EntityQuery.from("BestEfforts").where("athleteId", "==", athleteId);
return manager.executeQuery(athleteQuery).then(athleteQueryCompleted)
.then(manager.executeQuery(effortsQuery).then(effortsQueryCompleted))
.fail(queryFailed);
}
So I'm assuming I just don't understand the Q.defer() enough to use it properly or there is something else going on.
What is the correct syntax to accomplish this?
Ok, thanks to RainerAtSpirit for pointing me in the right direction to find this. I looked at John Papa's jumpstarter examples and he has a datacontext that does this under the primeData function.
So using the syntax he used there I was able to get it to work correctly like this:
getAthleteAndEfforts: function (athleteId, athleteQueryCompleted, effortsQueryCompleted) {
return Q.all([
datacontext.getAthlete(athleteId, athleteQueryCompleted),
datacontext.getAthleteEfforts(athleteId, effortsQueryCompleted)]);
}
I had seen the Q.all in the Q documentation but wasn't sure how to use it, but this example helped. I tested this and it works both in debug and release modes.
Not sure why the first version is working at all, but you'd return a promise when datacontext is making async calls.
function activate() {
return datacontext.getAthlete(loadAthlete);
}
or
function activate() {
return datacontext.getAthlete(loadAthlete).then( return datacontext.getOtherData(loadOtherData));
}
Check #John Papa's jumpstarter for more examples: https://github.com/johnpapa/PluralsightSpaJumpStartFinal/search?q=activate

MvvmCross vNext: ObservableColletion is defined in an assembly that is not referenced

I have got my PCL model to build now, which took a bit of time making plug-ins, however now in my Android UI project I get two errors when building it.
First error is:
The type 'System.Collections.ObjectModel.ObservableCollection`1<T0>' is defined in an assembly that is not referenced.
You must add a reference to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e,
Retargetable=Yes'. C:\ENM\Main\src\prod\Mobile\Stakeholder\UI.Android.vNext\Views\LocationsMapView.cs 40 32 UI.Android.vNext
The second error is:
foreach statement cannot operate on variables of type
'System.Collections.ObjectModel.ObservableCollection`1<BK.EMS.Stakeholder.Model.ViewModels.LocationViewModel>'
because 'System.Collections.ObjectModel.ObservableCollection`1<BK.EMS.Stakeholder.Model.ViewModels.LocationViewModel>'
does not contain a public definition for 'GetEnumerator'
C:\ENM\Main\src\prod\Mobile\Stakeholder\UI.Android.vNext\Views\LocationsMapView.cs 40 32 UI.Android.vNext
I have referenced the System.Windows assembly from the System.Windows.Droid project, which is supposed to forward ObservableCollection<>.
The lines where the error occurs:
private void AddLocationOverlays()
{
if (_itemizedOverlay.Size() > 0) _itemizedOverlay.ClearOverlayItems();
RunOnUiThread(() =>
{
foreach (var location in ViewModel.Locations)
{
_itemizedOverlay.AddOverlayItem(location);
}
_mapView.Invalidate();
});
}
The Locations property in my ViewModel looks like this:
public ObservableCollection<LocationViewModel> Locations
{
get { return _locations; }
set
{
_locations = value;
RaisePropertyChanged(() => Locations);
}
}
Nothing too complicated and works fine in the non-PCL models...
So how do I get around and fix this?
We now have a solution to this problem - see fix from Daniel Plaisted in Portable Class Library strong assembly reference problems in MonoTouch/MonoDroid
This fix is checked in at https://github.com/slodge/MvvmCross/commit/f6a88048467838e5ac5ca687744dc0b2d1958aa8
Update : See other answer. It appears we now have a solution to this problem!
I believe this is linked to this problem - Portable Class Library strong assembly reference problems in MonoTouch/MonoDroid
Which is linked to: https://github.com/slodge/MvvmCross/issues/41
This is raised with Xamarin as a bug: https://bugzilla.xamarin.com/show_bug.cgi?id=8035 and
I'm afraid I don't understand the recommended Strong Signing solutions right now.
Please upvote the bug report to alert the Microsoft PCL and Xamarin teams about this. The MS and Xamarin teams are talking to each other on this (albeit through me!), and I am hopeful we will find a way for either Microsoft or Xamarin to ship some signed DLLs.
In the meantime, some possible workarounds are:
Use IEnumerable access instead of ObservableCollection - the collection can still be an ObservableCollection instance, just don't reference it as an ObservableCollection in the UI code.
Try putting your iterating code in a class library rather than in an application project - bizarre as it feels, the compiler seems perfectly happy building the same code when its in a library rather than in an application
Try building in MonoDevelop with the Mono compiler - this doesn't seem to have the same strong name reference checks.
Looking at your sample code I would just try:
private ObservableCollection<LocationViewModel> _locations;
public IEnumerable<LocationViewModel> Locations
{
get { return _locations; }
set
{
if (value != null && !(value is ObservableCollection<LocationViewModel>)
{
throw new Exception("You must Set an ObservableCollection");
}
_locations = (ObservableCollection<LocationViewModel>)value;
RaisePropertyChanged(() => Locations);
}
}
then AddLocationOverlays could stay the same.
The only problem with this would be if you then wanted to bind to INotifyCollectionChanged on this collection - but I think you can find a way around this too if needed - e.g. you could somehow expose another INotifyCollectionChanged hook, or you could try using a hack involving an intermediary class library.
I accept that for now these are workarounds not solutions :/

Resources