how to view breeze client validation errors - breeze

I have read through the breeze validator information, but am not sure how to view the actual error that is occurring.
Error: client side validation errors encountered - see the entity Errors collection on this object for more detail.
I believe it's somewhere in entity.entityAspect.getValidationErrors() but am having trouble figuring out how to get the actual error out of it.
I am trying to insert a record into an entity and save changes when this error message occurs.

See :
http://www.breezejs.com/sites/all/apidocs/classes/ValidationError.html
http://www.breezejs.com/sites/all/apidocs/classes/EntityAspect.html#method_getValidationErrors
Simple example:
var errors = entity.entityAspect.getValidationErrors();
errors.forEach(function(ve) {
var errorMessage = ve.errorMessage;
var property = ve.property;
});
To get all of the errors in an EntityManager you can use
manager.getEntities().forEach(function(entity) {
var errors = entity.entityAspect.getValidationErrors();
//.. do something with the errors ..
});

You can 'catch' the errors when you try and save, like so:
manager.saveChanges()
.catch(function(error){
console.log("error catch", error, error.entityErrors);
});
Just keep in mind that any code after that will need to be in a
setTimeout(function() {}, 0);
as the catch is async.
This was you don't need to loop through all the entities in the app to find the ones with errors.

Related

How to refresh previously bound entity every time user visits the page

I just ran into a problem where I am not sure how to solve.
Background: I've got an App with two views:
1st one to input a number,
2nd one to see the details.
After the view switched to the detail view, I would call the bindElement() to get my data from the backend.
_onRoutePatternMatched: function(oEvent) {
// ...
this.getView().bindElement({
path: "/EntitySet('" + id+ "')"
});
},
Problem is that the ID is quite often the same, hence, the method will call the backend only if the ID is different from the last call.
So I tried to solve the problem by using the following:
this.getView().getModel().read("/EntitySet('" + id+ "')",{
success: function(oData, response) {
that.getView().setModel(oData, "");
}
});
By this, the data is always up to date. But now the binding is a bit different.
Binding with bindElement():
{
"id": "1234",
"propety1": "abc",
// ...
}
Binding with setModel() and id = 1234:
{
"EntitySet('1234')": {
"id": "1234",
"propety1": "abc",
// ...
}
}
For the first way, my binding looked like this:
<ObjectHeader title="{id}">
Now, it would have to look like this:
<ObjectHeader title="{/EntitySet('1234')/id}">
And here I have a problem, because the value of id (in this case 1234) will always be different and so the binding won't work. I can't bind directly to the ObjectHeader, because I will need some properties from the model later. That is the reason I am binding to the view so that all that remain available.
My idea was to edit the binding inside the success method of the read method. I would like to delete the surrounding element. Do you have an idea, how to do this? Or even a simpler/better idea to solve my pity?
Edit:
I forgot to mention the refresh method. This would be possible, but where do I have to put it? I don't want to call the backend twice.
Simply call the API myODataModel.invalidateEntry(<key>) before binding the context in order to retrieve the latest data.
// after $metadata loaded..
const model = this.getOwnerComponent().getModel("odata");
const key = model.createKey(/*...*/) //See https://stackoverflow.com/a/47016070/5846045
model.invalidateEntry(key); // <-- before binding
this.getView().bindElement({
path: "odata>/" + key,
// ...
});
From https://embed.plnkr.co/b0bXJK?show=controller/Detail.controller.js,preview
invalidateEntrydoc
Invalidate a single entry in the model data.
Mark the selected entry in the model cache as invalid. Next time a context binding or list binding is done, the entry will be detected as invalid and will be refreshed from the server.

Getting service metadata of SAPUI5 v2 ODataModel?

I try to get the service metadata of a sapui5 v2 odata model.
Code:
var oModel = new sap.ui.model.odata.v2.ODataModel(someServiceURL);
var oMetadata = oModel.getServiceMetadata();
This should work according to this page:
https://openui5beta.hana.ondemand.com/docs/guide/6c47b2b39db9404582994070ec3d57a2.html
Anyhow I got "undefined" for oMetadata.
If I change code to:
var oModel = new sap.ui.model.odata.v2.ODataModel({
loadMetadataAsync : false,
serviceUrl : someServiceURL
});
Still oMetadata === undefined
According to SDK documentation metadata should be loaded in sync:
Return the metadata object. Please note that when using the model with
bLoadMetadataAsync = true then this function might return undefined
because the metadata has not been loaded yet. In this case attach to
the metadataLoaded event to get notified when the metadata is
available and then call this function.
What is wrong with my code?
I am using (1.28.11):
<script src="https://sapui5.netweaver.ondemand.com/resources/sap-ui-core.js" ...
I started debugging the UI5 code and detected following line:
this.bLoadMetadataAsync = true;
I started debugging of SAPUI5 code and detected following line (seems to be called each time):
this.bLoadMetadataAsync = true;
Is it a bug? Or is something wrong with my code?
Solution:
The following worked for me in an actual application environment. I guess it not being fired in my fiddle was due to no actual data request being made:
var oModel = new sap.ui.model.odata.v2.ODataModel(<ServiceURL>);
oModel.attachMetadataLoaded(null, function(){
var oMetadata = oModel.getServiceMetadata();
console.log(oMetadata);
},null);
Lead up to the solution:
Ok so I started playing around with this a bit and found the following:
.getServiceMetadata() worked fine with sap.ui.model.odata.ODataModel.
with the sap.ui.model.odata.v2.ODataModel the request for the metadata was sent through the network but somehow .getServiceMetadata() returned undefined.
I tried to sap.ui.model.odata.v2.ODataModel.attachMetadataLoaded() but the event was never fired. (This only applied in the jsbin I used)
I will edit this with any further findings I make. If you have anything that should be included in my findings/testing just tell me.
Edit:
The bLoadMetadataAsync is a parameter you can set on the sap.ui.model.odata.ODataModel. The parameter is not in the API for sap.ui.model.odata.v2.ODataModel anymore. I assume that the async loading has been choosen as default.
Edit:
#user3783327 Reported a bug here: https://github.com/SAP/openui5/issues/564
As sirion already mentioned, the ODataModel has now an API named metadataLoaded which returns a promise accordingly. In the resolve function, we can definitely get the service metadata via getServiceMetadata().
myODataModel.metadataLoaded()
.then(() =>/* Do something with */myODataModel.getServiceMetadata());
Alternatively, we can also make use of ODataMetaModel which can be set on any ManagedObject (including View) and provides several useful accessors related to the service metadata. In order to get the meta model, we need to use the appropriate API from the ODataModel instead of instantiating the model directly:
myODataModel.getMetaModel().loaded()
.then(() =>/* Do something with */myODataModel.getMetaModel()/*...*/);
Documentation: Meta Model for OData V2

loop through model in mvc razor code behind

I am working on MVC4 App, and I am stuck at one point, I tried using google to help me, but without success. This might be more simple then I think, but coming from web forms and shifting to mvc is "painful" sometime.
I am trying to loop through the model I have and get the values stored in that model. I tried few approaches but I am getting an error everytime. This is what I have:
var modelAgentFilter = from s in _aa.Agents
where s.COUNTER == Convert.ToInt32(AgentID)
select s;
if (modelAgentFilter != null)
{
ViewBag.FirstName = // Get FirstName object here
}
Thanks in advance for your comments.
Laziale
EDIT:
I did include for loop like this:
if (modelAgentFilter != null)
{
foreach (var property in modelAgentFilter)
{
string test = property.ADDRESS;
}
}
But when the compiler will reach the foreach step I am getting this error: "LINQ to Entities does not recognize the method 'Int32 ToInt32(System.Object)' method, and this method cannot be translated into a store expression."
I can get to the properties of the var model using that foreach look but as soon as the compiler will try to loop the model that error pops up.
Thanks again
LINQ to Entities does not recognize any methods. You can't use even ToString() in LINQ expression. You need first convert your value and than add it in LINQ.
In your example you need to do something like following:
var _agentID = int.Parse(AgentID);
var modelAgentFilter = from s in _aa.Agents
where s.COUNTER == _agentID
select s;

AJAX Form Update for a single Field

I'm trying to implement x-editable for my Form. For this is need to find a way to update the entity on a single-property-basis. The biggest headache this is giving me is the way of how a single data could be validated. To my understanding the setValidationGroup() doesn't appear to work (or i am doing this completely wrong). Here's what i tried:
if ($request->isPost()) {
$form->setData($request->getPost());
if($request->isXmlHttpRequest()) {
$filters = $form->getInputFilter();
$filters->setValidationGroup(
$this->params()->fromPost('name')
);
$form->setInputFilter($filters);
}
if ($form->isValid()) {
$objectManager->flush();
if ($request->isXmlHttpRequest()) {
$response = $this->getResponse();
$response->setStatusCode(Response::STATUS_CODE_200);
return $response;
}
} else {
$errors = $form->getMessages();
\Zend\Debug\Debug::dump($errors);
die("notvalid");
}
}
The checks for isXmlHttpReqiest serve the purpose of #1 to minify the validation-group to just one Element and #2 to send out specific responses that work with the x-editable plugin for jQuery.
Current Error: all FormFields are validated. I get an error-message for two required fields whose isEmpty-Validator are called.
I think the way you're calling setValidationGroup is wrong Sam, it's a form method, and you give it an array of field names
if($request->isXmlHttpRequest()) {
$form->setValidationGroup(array(
'name',
));
}
Solution was:
Learn to freaking set your inputFilters correctly. I don't know why i didn't get any parsing error, but there was a string error while fetching the correct inputFilters, so actually there was no inputFilter attached at all.
Since the Form has valid default data, error only occured when validating single elements.
Essence:
Start writing Unit Tests ....

Strange Node.JS error

I have running in my Mac a Node.JS server, and, I access to it from other computer, the server doesn't crash, but, I don't know why, the application crashes when I access from my iPad. If I access from Safari, the server works, but, with Chrome for iPad, the app crash!
This is the error: TypeError: Cannot read property 'following' of null. Why this happens?
EDITED:
app.get('/home', middleware.yeses, function (req, res){
console.log(req.session.user + "\n\n");
UserModel.find({ user: req.session.user }, function (err, user){
console.log(user);
res.render('home.ejs', {
username: req.session.user,
avatar: user[0].avatar,
following: user[0].following.length,
followers: user[0].followers.length
});
});
});
EDITED:
I changed the console.log(user); to this console.log(user[0].following). And there's no problem. I don't know why, there's a problem with it in the locals.
This occurs because the JavaScript is throwing an exception. Somewhere in the code, the there is a variable that is assigned to null and the property following is being accessed on that variable. This operation raises an exception.
var obj = null;
obj.following; // exception thrown!
It's impossible to help you more. With the info and code you've provided (very little of either). But look for where you are accessing a following property and debug from there.
Update:
It appears user[0] is null. Why? No idea. That depends on other code you haven't posted. WHere is user declared and populated? Is it an array? Because that would be strange for a variable named user.

Resources