breeze entity type has recursive definition - breeze

the following code will often run out of stack space because the type Entity has a property named EntityAspect, which has a property named Entity of type Entity which points to the owning Entity. This recursive definition causes several tools to fail or run incredibly slow, but most notably, knockout. Can anything be done to address this?
var custType = _this.metadataStore.getEntityType("Customer");
var cust1 = custType.createEntity();
var js = ko.toJS(cust1);

I haven't actually tried this yet but I think you can do this
var js = ko.mapping.toJS(cust1, {
ignore: ['entityAspect']
});

I found I needed to ignore both entityAspect and entityType (snippet from custom datasource kendo datasource):
this.entityManager.executeQuery(query)
.then(function (xhr) {
if (self.autoMapToJS) { // Breeze entities contain recursive properties (ugh!) - eliminate those
payload.data = ko.mapping.toJS(xhr.results, {
ignore: ['entityAspect', 'entityType']
});
} else {
payload.data = xhr.results;
}
if (self.inlineCount) {
payload.total = xhr.inlineCount;
}
options.success(payload); // notify the DataSource that the operation is complete
})
.fail(function (rejected) {
payload.error = rejected;
})
.done(); // terminate chain of promises
}
In particular, trying to use with grids (wijmo & kendo), I was forced to map breeze data or enjoy stackoverflows as those controls would iterate through the properties.

Related

Is it possible to 'assert' a type using .where()?

I have a list<Components> components; which is sub-class of Bonus, hence Bonus are Components too.
The .toRect() method is defined in the Bonus class but not in the Components class.
I'm making sure I'm only calling .toRect() in Bonus objects, so there should be no problem, but Dart is keeping me from running the code with the following error:
The method 'toRect' isn't defined for the type 'Component'.
Is there a way to go around this problem without the need to define .toRect() on the Components Class?
void checkForCollision() {
controller.components.where((c) => c is Bonus).forEach((bonus) {
if (this.toRect().contains(bonus.toRect().topLeft) ||
this.toRect().contains(bonus.toRect().topCenter) ||
this.toRect().contains(bonus.toRect().topRight)) {
this.remove = true;
}
});
}
Could do:
.forEach((bonus) {
Bonus bonus = bonus;
.....
or
(controller.components.where((c) => c is Bonus) as List<Bonus>).forEach((bonus) {
Use whereType to filter on types. It's like where that just checks for a type, but it also ensures that the resulting iterable has that element type.
controller.components.whereType<Bonus>().forEach((bonus) {
... bonus.toRect ...
});
The Dart style guide recommends not using a function literal with forEach, use a for-loop instead:
for (var bonus in controller.components.whereType<Bonus>()) {
... bonus.toRect ...
}
If you are doing that anyway, you can also just do:
for (var component in controller.compenents) {
if (component is Bonus) {
.. component.toRect ...
}
}
The type promotion from the is check will ensure that you can call toRect.
This very directly specifies what's going on, without creating unnecessary intermediate iterables.

Analyzer package - How to recursively search in the results of parseDartFile()

Currently trying to understand 'analyzer' package, because I need to analyze and edit .dart file from another file (maybe it's a terrible idea).
I think I understand how to go deep into the childEntities tree.
But can't understand how to search in it.
I mean, theoretically I can write a recursive search that will find me a class named "FindABetterSolution". But is there a built in method for that?
What I'm trying to do:
var file = parseDartFile("test.dart");
file.childEntities.forEach((SyntacticEntity entity) {
if(entity is AstNode) {
//then it has its own child nodes which can be AstNode-s or Tokens.
} else if(entity is Token) {
Token token = entity;
print("${token.lexeme} ${token.type} ${token.runtimeType} ${token.keyword}");
//this will output "class KEYWORD KeywordToken CLASS" for "class" in "class MyClass {"
}
});
//I need a way to find certain functions/classes/variables/methods e.t.c.
var myClassNode = file.searchClass("MyClass", abstract: false);
var myMethod = myClassNode.searchMethod("myMethod", static: true);
var globalFunction = file.searchFunction("myFunc", returns: "bool");
UPD: Ok, I think I found a way to search and replace nodes. But how to insert new node after/before another?
You can call file.accept() or file.visitChildren() with a RecursiveAstVisitor that implements visitClassDeclaration, visitMethodDeclaration, or visitFunctionDeclaration.

Get a promise with angular2 in dart from an http request?

It seems in the 2.0.0-beta.12 build they removed angular2.http from dart in favor of using dart's built in http classes.
However if you were to do something like the following then property is null until the request sets the property.
class Component {
var property;
Component() {
HttpRequest.getString("/path/to/something")
.then((resp) {
property = JSON.decode(resp);
});
}
}
What we really want is a promise place holder for the property until the promise is resolved and the view is updated. So how do you do it in angular2 with dart?
Or is there a different dart/angular2 idiomatic way to do it?
HttpRequest.getString(...) returns a Future (Promise in JS/TS land) otherwise you wouldn't be able to call .then(...) on the result.
You can either use async / await
class Component {
var property;
Component() async {
await HttpRequest.getString("/path/to/something")
.then((resp) {
property = JSON.decode(resp);
});
doSomethingAfterRequestReturned();
}
}
nope - you can't use async / await in a constructor.
Alternatives are static methods or an extra call after object creation. Doing extensive work in the constructor is bad practice anyway.
class Component {
Future<Component> createNewInstance() async {
var c = new Component();
await HttpRequest.getString("/path/to/something")
.then((resp) {
c.property = JSON.decode(resp);
});
return c;
}
var property;
}
and use it like
Component.createNewInstance().then((c) => print(c.property));
with an extra call
class Component {
getData() {
return HttpRequest.getString("/path/to/something")
.then((resp) {
property = JSON.decode(resp);
});
}
var property;
}
and use it like
var c = new Component()
c.getData().then((_) => print(c.property));

JavaScript module pattern with sub-modules cross access or better pattern?

Perhaps this is the wrong approach to my problem, but that is why I'm here. In the code below is a sample of a JavaScript module pattern with sub-modules. As I build this, I realize that some sub-modules need to "call" each other's methods.
I know that it would be wrong to use the full call admin.subModuleB.publicB_2(); but its the only way since the IIFE functions cannot call "themselves" until instatiated, ex. "module" is not available in the primary namespace, etc...
My thought is that this pattern is incorrect for my situation. The purpose of the module encapsulation is to keep things private unless reveled. So what would be a better pattern?
var module = (function($, window, document, undefined) {
return {
subModuleA : (function() {
var privateA = 100;
return {
// We have access to privateA
publicA_1 : function() {
console.log(privateA);
// How do I use a method from publicB_1
// the only way is:
module.subModuleB.publicB_2();
// but I don't want to use "module"
},
publicA_2 : function() {
console.log(privateA);
}
}
})(),
subModuleB : (function() {
var privateB = 250;
return {
// We have access to privateB
publicB_1 : function() {
console.log(privateB);
},
publicB_2 : function() {
console.log(privateB);
// I have access to publicB_1
this.publicB_1();
}
}
})()
}
})(jQuery, window, document);
What you actually have is an issue with dependencies. Sub module A has a dependency on Sub module B. There are two solutions that come to mind.
Define both modules as their own variables inside the function closure, but return them together in a single object.
What you actually want is instantiable classes where Class A has a dependency on Class B.
Since solution #1 is the closest to your current code, let's explore that first.
Define Both Modules Separately Inside the Closure
var module = (function($, window, document, undefined) {
var SubModuleA = function() {
var privateA = 100;
return {
// We have access to privateA
publicA_1 : function() {
console.log(privateA);
// Refer to SubModuleB via the private reference inside your "namespace"
SubModuleB.publicB_2();
// but I don't want to use "module"
},
publicA_2 : function() {
console.log(privateA);
}
};
}();
var SubModuleB = function() {
var privateB = 250;
return {
// We have access to privateB
publicB_1 : function() {
console.log(privateB);
},
publicB_2 : function() {
console.log(privateB);
// I have access to publicB_1
this.publicB_1();
}
};
}();
// Return your module with two sub modules
return {
subModuleA : SubModuleA,
subModuleB : SubModuleB
};
})(jQuery, window, document);
This allows you to refer to your two sub modules using local variables to your module's closure (SubModuleA and SubModuleB). The global context can still refer to them as module.subModuleA and module.subModuleB.
If Sub Module A uses Sub Module B, it begs the question of whether or not Sub Module B needs to be revealed to the global context at all.
To be honest, this is breaking encapsulation because not all the functionality of Sub Module A exists in Sub Module A. In fact, Sub Module A cannot function correctly without Sub Module B.
Given your particular case, the Module Pattern seems to be an Anti Pattern, that is, you are using the wrong tool for the job. In reality, you have two classifications of objects that are interdependent. I would argue that you need "classes" (JavaScript Constructor functions) and traditional OOP practices.
Use JavaScript Constructor Functions ("classes")
First, let's refactor your "module" into two classes:
var module = (function($, window, document, undefined) {
function ClassA(objectB) {
var privateA = 100;
this.publicA_1 = function() {
console.log(privateA);
objectB.publicB_2();
};
this.publicA_2 = function() {
console.log(privateA);
};
}
function ClassB() {
var privateB = 250;
this.publicB_1 = function() {
console.log(privateB);
};
this.publicB_2 = function() {
console.log(privateB);
this.publicB_1();
};
}
// Return your module with two "classes"
return {
ClassA: ClassA,
ClassB: ClassB
};
})(jQuery, window, document);
Now in order to use these classes, you need some code to generate the objects from the constructor functions:
var objectA = new module.ClassA(new module.ClassB());
objectA.publicA_1();
objectA.publicA_2();
This maximizes code reuse, and because you are passing an instance of module.ClassB into the constructor of module.ClassA, you are decoupling those classes from one another. If you don't want outside code to be managing dependencies, you can always tweak ClassA thusly:
function ClassA() {
var privateA = 100,
objectB = new ClassB();
this.publicA_1 = function() {
console.log(privateA);
objectB.publicB_2();
};
this.publicA_2 = function() {
console.log(privateA);
};
}
Now you can refer to module.ClassB using the name within the function closure: ClassB. The advantage here is that outside code does not have to give module.ClassA all of its dependencies, but the disadvantage is that you still have ClassA and ClassB coupled to one another.
Again, this begs the question of whether or not the global context needs ClassB revealed to it.

ComplexType Properties Array Bug

I found a bug concerning the ComplexType properties. I have an Object which has a property which is a collection of other objects which I defined in the client-side metadata as a Complex property, i.e. "isComplexType: true". However all properties of a complex type are set to 'undefined'. I did a bit of debugging and found this:
// target and source may not be entities that can also be complexTypes.
function updatePropertyFromRawEntity(dp, target, rawSource) {
var val = getPropertyFromRawEntity(rawSource, dp);
if (val === undefined) return;
if (dp.isComplexProperty) {
var coVal = target.getProperty(dp.name);
dp.dataType.dataProperties.forEach(function (cdp) {
// recursive call
updatePropertyFromRawEntity(cdp, coVal, val);
});
} else {
target.setProperty(dp.name, val);
}
}
The rawSource parameter is an array(in case of complexTypes) is an array of objects. So the problem is when invoking the getPropertyFromRawEntity(), it passes an array not an object:
function getPropertyFromRawEntity(rawEntity, dp) {
var propName = dp.nameOnServer || dp.isUnmapped && dp.name;
return parseValueForDp(rawEntity[propName], dp);
}
So rawEntity[propName] will always be undefined because its an array.
A Breeze ComplexType has a well defined structure specified by metadata. Any property, (except) the key can have its datatype be a complexType. However, what you want, I think, is an "untyped" structure. This can be accomplished by defining the property as having a data type of "Undefined", something like:
var newProp = new DataProperty({
name: "Foo"
dataType: DataType.Undefined,
isNullable: true,
isUnmapped: true
});
entityType.addProperty(newProp);
The "Undefined" dataType will accept data of any type and structure.

Resources