Property Metadata Binding Assertion Failed - odata

I have a View in my SAPUI5 application where I am creating a OData Model.
In the next step I want to use his metadata to bind a Property.
My error message is
abap.js:64 Assertion failed: COLUMN/#sap:label is not a valid property path
I think here is another mistake because before i tried this, I had always a OData Model which i defined in the manifest file and it worked fine - but now when creating a Model in the same view it doesn't work.
I also thougt about to set the Model to the View, but I think its not neccessery because in the Path I am saying, please look at "oModel" OData Model for your data. {oModel</....
Did I forgot something?
// creating model
var oModel = new sap.ui.model.odata.v2.ODataModel("/sap/opu/odata/sap/xxxx/", "oModel");
var oLabel = new sap.ui.comp.smartfield.SmartLabel({
text: "{oModel>/#showcase/" + column + "/#sap:label}" // {ODataModel>/#showcase/" + column + "/#sap:label}" //
});

the "oModel" inside the line
text: "{oModel>/#showcase/" + column + "/#sap:label}"
refers to a name, under which you can assign the model to any Control that is inherited from sap.ui.base.ManagedObject. it has no relationship to the variable name "oModel" that you use to create the model in JS.
the following should work (note, I replaced one occurrence of oModel with bla, the other with blubber to point out the difference
var bla = new sap.ui.model.odata.v2.ODataModel("/sap/opu/odata/sap/xxxx/");
var oLabel = new sap.ui.comp.smartfield.SmartLabel({
text: "{blubber>/#showcase/" + column + "/#sap:label}"
});
oLabel.setModel(bla, "blubber")
or, alternatively:
var oLabel = new sap.ui.comp.smartfield.SmartLabel({
models: {
"blubber": new sap.ui.model.odata.v2.ODataModel("/sap/opu/odata/sap/xxxx/")
},
text: "{blubber>/#showcase/" + column + "/#sap:label}"
});

Related

document.querySelectorAll to find item based on multiiple condition?

I am trying to find div based on combination of class name and data attribute. But it doesn't seems to returning any value.
var products = document.querySelector("div.productDisplay").querySelectorAll("[data-productId='" + id + "']");
The first .querySelector() call will only return a single element. If that does not match the selector in the querySelectorAll() call then no elements will be retured.
Try using a single selector, such as:
var products = document.querySelector("div.productDisplay[data-productId='" + id + "']");

How to create dynamic Entity Framework query

how to create dynamic Entity Framework query. where we are getting dbset name from user as parameter and othere condition like column names and other where clause conditions
Disclaimer: I'm the owner of Eval-Expression.NET
This library lets you evaluate, compile, and execute code at runtime. Almost all the C# language is supported.
You can find some example for LINQ Dynamic here: http://eval-expression.net/linq-dynamic
But you can do more like specifying the dbset and condition
Example
string set = "Entity1";
string whereClause = "x.ID > 2";
// CREATE the expression
string expression = "ctx." + set + ".Where(x => " + whereClause + ").ToList();";
// USING a context variable
var ctx = new EntityContext();
var list1 = Eval.Execute(expression, new {ctx});
// USING a context in the expression
EvalManager.DefaultContext.RegisterType(typeof(EntityContext));
var list2 = Eval.Execute("var ctx = new EntityContext();" + expression);

SAPUI5 get oData model from table binding

I have binded a Table using oData like below.
<Table id="myTableID"
class="sapUiResponsiveMargin"
items="{Items}"
noDataText="{i18n>NoDataText}"
updateFinished="onUpdateFinished"
width="auto">
Now I need to retrieve this oData model from the view rather than calling the web service again.
I have tried the below,
var path = this.getView().getElementBinding().getPath();
var oModel = this.getView().getModel();
which returns the model from the parent view.
Is there a way to achieve this?
Just use this.getView().byId("myTableID").getModel();
I assume that you want only the items that are bound to the table.
var sPath = oTable.getBindingPath("items");
This gives you the path that you have bound to the items aggregation.
var oModelObject = oTable.getModel().getProperty(sPath);
This fetches only the table bound objects from your model
Edit oTable is your table object. var oTable = this.getView().byId("myTableID");

sapui5 table shows only the same record [duplicate]

This question already has an answer here:
OData Model Not Working
(1 answer)
Closed 20 days ago.
I have created a webservice and trying to bind data using oData protocol in SAPUI5.
I have created a table:
createContent : function(oController) {
jQuery.sap.require("sap.ui.table.Table");
//Create table control with properties
var oTable = new sap.ui.table.Table({
width : "100%",
rowHeight : 50,
title : "Lst of Items",
selectionMode : sap.ui.table.SelectionMode.None
});
oTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({
text : "PO Number"
}),
template : new sap.ui.commons.TextView({
text : "{PoNumber}"
}),
}
));
oTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({
text : "Item"
}),
template : new sap.ui.commons.TextView({
text : "{PoItem}"
}),
}
));
//Filter values for a certain PO
var aFilter = [];
aFilter.push( new sap.ui.model.Filter("PoNumber", sap.ui.model.FilterOperator.EQ, "4500000043") );
oTable.bindRows({
path: "/PurchaseOrderItemCollection",
filters: aFilter
});
return oTable;
}
The output should be as follows:
PONumber POItem
4500000043 0010
4500000043 0020
But what I get is:
PONumber POItem
4500000043 0020
4500000043 0020
So it shows the last item twice and doesn't show the first item. If I put a break point in my web service code then it is populated correctly.
The data model is created in the following way:
var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, false, "user", "passw");
sap.ui.getCore().setModel(oModel);
I have encountered this. Problem is with your data model. Ensure that for the entity both PO number and PO item are marked as keys. Refresh any metadata cache, ensure that both properties appear as keys and try again. It should work.
Thanks
Krishna
My understanding is every entity/entry in the collection should have a unique id <entry><id>...</id></entry>.
And in my case, the returned collection had no ids set for the entities. So the bound ui element finds multiple objects with same id (in this case empty id) and ends up displaying value which it finds the last.
The same should apply even if the id is same across all entities.
Hope it helps, if you have not already found what the problem is.
Thanks,

Breeze import with entity extended property of ko.observableArray() throwing error

Running into an error during import for entities extended with a ko.observableArray() property, vs. being extended as a simple array [] type in the constructor.
var customerCtor = function () {
this.extendedProp = ko.observable(true);
//this.extendedArray = ko.observableArray(); // causes error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
this.extendedArray = []; // this works just fine
};
I created a test along-side the Breeze v1.3.6 DocCode: exportImportTests.js "stash entire cache locally and restore" as my starting point, and here is the new test:
test("w/extended Customer, stash entire cache locally and restore", 3, function () {
var em1 = newEm();
var store = em1.metadataStore;
// extend Customer with observables
var customerCtor = function () {
this.extendedProp = ko.observable(true);
this.extendedArray = ko.observableArray(); // causes error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
//this.extendedArray = []; // but this will work just fine?
};
store.registerEntityTypeCtor("Customer", customerCtor);
var expected = testData.primeTheCache(em1);
// grab first Customer, push value onto extendedArray prop
var custEntity = em1.getEntities(expected.customerType)[0];
custEntity.extendedArray().push('some-value'); // even when defined as [], Breeze re-writes field as ko.observable
var exportData = em1.exportEntities();
var stashName = "stash_everything";
window.localStorage.setItem(stashName, exportData);
var importData = window.localStorage.getItem(stashName);
var em2 = new EntityManager(); // virginal - so register ctor on this instance
var store2 = em2.metadataStore;
store2.registerEntityTypeCtor("Customer", customerCtor);
em2.importEntities(importData);
var entitiesInCache = em2.getEntities();
var restoreCount = entitiesInCache.length;
equal(restoreCount, expected.entityCount,
"should have restored expected number of all entities");
var restoredCustomer = em2.getEntities(expected.customerType)[0];
ok(restoredCustomer.extendedProp(), 'extended property present');
ok(restoredCustomer.extendedArray().length > 0, 'extended Array present and has data');
});
An em2.importEntities(importData); throws the error:
Error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
at Error (<anonymous>)
at h [as extendedArray] (http://localhost:47595/Scripts/knockout-2.2.1.js:44:167)
at ctor.initializeEntityPrototype.proto.setProperty (http://localhost:47595/Scripts/breeze.debug.js:14634:31)
at updateTargetPropertyFromRaw (http://localhost:47595/Scripts/breeze.debug.js:13062:24)
at aspectName (http://localhost:47595/Scripts/breeze.debug.js:13025:13)
at Array.forEach (native)
at updateTargetFromRaw (http://localhost:47595/Scripts/breeze.debug.js:13023:19)
at em._inKeyFixup (http://localhost:47595/Scripts/breeze.debug.js:12601:17)
at Array.forEach (native)
at importEntityGroup (http://localhost:47595/Scripts/breeze.debug.js:12568:28)
As Breeze always rewrites constructor fields (in my case for KO), defining as [] works. But not sure why this would happen when the property is pre-defined?
Anyone run into this, or have I missed a doc note somewhere?
We'll look at it.
Yes, Breeze assumes every property added in a constructor is supposed to be rewritten per the prevailing "model library" which, in your case, is KO. Therefore, no surprise that the array becomes a ko.observableArray.
Moreover, because such a property is presumed to be under Breeze's jurisdiction, we have to tie it into Breeze observability and serialization mechanisms which means we re-write it as a Breeze-flavored observable array. Such an array is a computed.
Evidently there is some problem with the way we're doing this for a property which is "unmapped". We'll look at that.
N.B.: I am assuming (and your code confirms) that the array property, extendedArray, is an "unmapped property" in the Breeze sense. That should be fine.
You should not mention mapped collection navigation properties in your constructor. There is no valid reason to do so that I can think of. The main reason to mention a mapped property in the constructor is (a) to give it a default value or (b) make it available to a custom (unmapped) computed property. There is no reasonable alternative default value for a collection navigation property (empty is the default) and it would be rare/avoidable to include it in a computed.

Resources