Newly added line item is getting removed after making changes in data which is already bound to sap.m.Table [duplicate] - odata

This question already has answers here:
Add a New Item to a Table / List
(2 answers)
Closed 17 days ago.
We have to perform edit functionality where we have to take two scenarios into consideration:
Make changes in existing entries.
Add new entries and update the old entries.
In the 2nd scenario, when we are trying to add a new entry, it is getting added to sap.m.Table but if we make any change in the old entry then the newly added line item is disappearing.
let oContextLineItemEntry = oLineItmTab.getModel().createEntry("/EntityName", {
properties: NewLineItem,
});
let oTmp = oLineItmTab.getBindingInfo("items").template,
oItem = oTmp.clone();
oItem.setBindingContext(oContextLineItemEntry);
oLineItmTab.addItem(oItem);
Here NewLineItem is an object which I want to add and it is blank. It is initiated like below:
NewLineItem = oLineItmTab.getItems()[0].getBindingContext().getObject();
After this, I have removed all the values of the objects attribute.
I tried with OData V2 OneWay binding, but it didn't work.
I saw framework behavior is triggering this interaction
onChange started
onChange completed
I went through these questions on SAP Community:
https://answers.sap.com/questions/699607/newly-added-table-row-disappearing-when-changing-p.html
https://answers.sap.com/questions/13305104/ui5-controls-and-onchange-event-in-a-sapuitabletab.html

After you bind an aggregation it will be managed by the data binding. Therefore you should not try to modify the aggregations. Instead, do the changes in the model and then the aggregation should be updated according to data in the model. e.g.
let newRow = {key: "_your_unique_id_", value: ""};
let model = table.getModel();
let tableData = model.getProperty("/tableEntityName");
tableData.unshift(newRow);
model.setProperty("/tableEntityName", tableData);
Besides that consider to set the growing property of the table to true.

We had raised an OSS note for this issue to which SAP replied, this is not and issue with UI control but the way to use it.
Basically we are not supposed to add new entries when OData binding is being used.

Related

Microsoft Graph API remove Check List Item

I have a plannerTask and in its Details it has a CheckList. I use it to programatically insert CheckListItems in it, and it all works like a charm when inserting or retrieving the tasks.
My problem arrives when I am going to insert a new CheckListItem and the CheckList already has 20 items. It returns a MaximumChecklistItemsOnTask (because it is forbidden to insert more than 20 items in a check list).
Solution could be to remove the oldest item, but I am not able to do it. I have tried this:
var elementToRemove = oldDetails.Checklist.Where(c => c.Value.IsChecked).OrderBy(c => c.Value.LastModifiedDateTime).First();
oldDetails.Checklist = oldDetails.Checklist.Where(c => c.Value.LastModifiedDateTime <> elementToRemove.Value.LastModifiedDateTime);
But it throws a casting error in the second line:
Unable to cast object of type
'WhereEnumerableIterator1[System.Collections.Generic.KeyValuePair2[System.String,Microsoft.Graph.PlannerChecklistItem]]'
to type 'Microsoft.Graph.PlannerChecklistItems'.
Which is the right way to remove the oldest element from the ChecklistItem?
UPDATE:
In first place I retrieve a plannerTask from the server. Then I get the details from this plannerTask. So oldDetails is a plannertaskdetails object (https://learn.microsoft.com/en-us/graph/api/resources/plannertaskdetails?view=graph-rest-1.0). Inside the plannertaskdetails object (oldDetails), I have the plannerchecklistitems object (oldDetails.Checklist): https://learn.microsoft.com/en-us/graph/api/resources/plannerchecklistitems?view=graph-rest-1.0.
If plannerchecklistitems were just a List, it would be as easy as list.Remove(item), but it is not a normal list, and that is why I am not able to remove the item.
UPDATE 2:
I have found this way to remove the item from oldDetails:
oldDetails.Checklist.AdditionalData.Remove(elementToRemove.Key)
But, the the way I send the changes to the server is this:
await graphClient.Planner.Tasks(plannerTask.Id).Details.Request().Header("If-Match", oldDetails.GetEtag).UpdateAsync(newDetails)
As it is a PATCH request (not a PUT one), I only have in newDetails the records that have changed, it is, the new records. How could I specify there that a record has been deleted from the list? Sorry if my English is not good enough to express myself properly, but what I mean is that newDetails is not the full list, it only contains the records that must be added and I do not know how to specify in that request that one record must be deleted.

Iteration of two identical Set using Java Streams [duplicate]

This question already has answers here:
Difference between `Optional.orElse()` and `Optional.orElseGet()`
(9 answers)
When I need to use Optional.orElseGet() over Optional.orElse()
(3 answers)
Closed 2 years ago.
I have two HashSets with same type of objects. My search criteria is like, search in first set and if not present then search in another set. I had tried with Stream layer with following steps as given below
Set<MyObject> firstSet = new HashSet<>();
Set<MyObject> secondSet = new HashSet<>();
and these two sets are having some values.
Predicate<MyObject> match = myObject -> StringUtils.equals(myValue, myObject.getMyValue());
firstSet.values().stream().filter(match).findFirst()
.orElse(secondSet.values().stream().filter(match)
.findFirst().orElseThrow(()-> new MyException()));
My matching object is in First Set and i have tried to get it by manually and i got it... but using the above iteration, i always get the exception even when the first set has the matched object. Kindly correct me.. thanks is advance.
Your problem is that you are not using Optional.orElse as expected.
When you use Optional.orElse, its parameter is evaluated eagerly. This means that your second set is being searched first, to resolve the parameter of your first set's Optional.orElse.
Instead, use Optional.orElseGet, which receives a Supplier that is evaluated lazily:
firstSet.stream()
.filter(match)
.findFirst()
.orElseGet(() -> secondSet.stream()
.filter(match)
.findFirst()
.orElseThrow(()-> new MyException()));
EDIT: As suggested by Holger in the comments, there is an easier way:
Stream.of(firstSet, secondSet)
.flatMap(Set::stream)
.filter(match)
.findFirst()
.orElseThrow(MyException::new);
Streaming the sets first and then calling flatMap ensures that elements of the first set will all appear before elements of the second set.

Looping through list of objects created by createEntry() and editing their properties before doing submitChange()

Good afternoon fellow developers,
I have come across a scenario where I found myself needing to retrieve the list of pending changes from my model and editing a specific property of those entries before sending them to my back-end.
These are new entities I created using the createEntry() method of the OData model v2. But, at the time of creation of said entities, I do not possess the value I need to add to them yet. This is the list of entities I retrieve by using the getPendingChanges() method on my model:
What I need to do is to loop through each of these newly created entities and set a specific property into them before actually sending them to my back-end with the submitChanges() method. Bare in mind that these are entry objects created by the createEntry() method and exist only in my front-end until I am able to submit them with success.
Any ideas that might point me in the right direction? I look forward to reading from you!
I was able to solve this issue in the following way:
var oPendingChanges = this.model.getPendingChanges();
var aPathsPendingChanges = $.map(oPendingChanges, function(value, index) { return [index];});
aPathsPendingChanges.forEach(sPath => oModel.setProperty("/" + sPath + "/PropertyX","valueFGO"));
The first two instructions retrieve the entire list of pendingChanges objects and then builds an array of paths to each individual entry. I then use that array of paths to loop through my list of pending changes and edit into the property I want in each iteration of the loop. Special thanks to the folks at answers.sap for the guidance!

How to reload a ResourceTable programmatically in Laravel Nova?

I have a custom resource-tool (ledger entry tool) that modifies values of a resource as well as insert additional rows into related resources.
"Account" is the main resources.
"AccountTransaction" and "AccountLog" both get written to when a ledger entry is created. And through events, the account.balance value is updated.
After a successful post of a ledger entry (using Nova.request) in the resource-tool, I would like the new balance value updated in the account detail panel, as well as the new entries in AccountTransaction and AccountLog to be visible.
The simple way would be to simply reload the page, but I am looking for a more elegant solution.
Is it possible to ask these components to refresh themselves from within my resource-tool vue.js component?
Recently had the same issue, until I referred to this block of code
Nova has vuex stores modules, where they have defined storeFilters.
Assigning filters an empty object and then requesting them again "reloads" the resources. Haven't done much more research on this matter, but if you are looking for what I think you are looking for, this should be it.
async reloadResources() {
this.resourceName = this.$router.currentRoute.params.resourceName || this.$router.currentRoute.name;
if (this.resourceName) {
let filters_backup = _.cloneDeep(this.$store.getters[`${this.resourceName}/filters`]);
let filters_to_change = _.cloneDeep(filters_backup);
filters_to_change.push({});
await this.$store.commit(`${this.resourceName}/storeFilters`, filters_to_change);
await this.$store.commit(`${this.resourceName}/storeFilters`, filters_backup);
}
},

What is the right way to append entity from one manager to another in breeze?

What is the right way to append entity from one manager to another?
Straight forward attempts result in overwriting entities or in warning about the same entity key...
var entity = em1.getEntities()[0];
em1.deattachEntity(entity);
// assume em2 already has entities
em2.attachEntity(entity);
I believe there should be some in-build functionality for appending entries to another non empty manager or for generating an unique key for selected manager.
Any suggestions?
UPDATE:
I did read the documentation and tried to do it via exportEntities and exportEntities:
var entity = em1.getEntities()[0];
var export = em1.exportEntities([entity], false);
//here em2 already has entity with the same key as entity that I want to add
var import = em2.importEntities(export, { mergeStrategy: breeze.MergeStrategy.Disallowed });
This gives me an error: A MergeStrategy of 'Disallowed' prevents Picture:#Macaw.Whitelabel.WebAPI.Models--1 from being merged
I really don't understand how to append entities....
UPDATE2:
I did discover that manually assigning id of the attached entity solves the problem and error disappears.
Is there a way to make it not manually but using breeze?

Resources