Why am I getting oEvent.getParameter('data') undefined on dataReceived event? - odata

this.getView().bindElement({
path: `/Employees('${this._userId}')`,
parameters: { expand: 'aaa,bbb,ccc' },
events: {
dataReceived: (oEvent) => {
this.getView().setBusy(false)
debugger
}
}
});
I can see data in the response of the $batch request.
When I put a breakpoint in the dataReceived function handler, I can also see the data via this.getView().getModel().getProperty(this.getView().getBindingContext().getPath()).
The parameter oEvent.mParameters.data exists, but the value is undefined.
If I leave out expand, the data is set. Do all entities of an associated entityset need to have an association to its parent?

This is by design according to the API reference of dataReceived:
dataReceived
[...] This event may also be fired when an error occurred.
Param
type
description
data
string
The data received; is undefined in error cases
You must have somewhere an error message in the $batch response, or the request was somehow aborted.
The missing data parameter is currently the only documented indicator for a failed request on bindObject/bindElement.
PS: See also https://github.com/SAP/openui5/issues/2263

Related

SAPUI5 Send oData Request to Changeset

I would like to send a batch request to the changeset in the backend from my UI5 application. I did the following:
I created an Entity in my segw service. In the "changeset_begin" method I set the cv_defer_mode to true for my Entity.
In the frontend I tried to send a call to the backend. But somehow it doesnt work and I cant set a breakpoint in the ChangeSet. Are my syntax wrong? Thank you very much!
oDataModel.create("/MyEntitySet", { // in a loop, values are changed
properties: {
Key: item[i].getKey(),
Salesorder:"347854"
Department: "HR"
}
});
oDataModel.submitChanges({ // executed after loop
success: function (oData) {
oDataModel.refresh();
}
});
According to the API the method you are looking for is createEntry.
Creates a new entry object which is described by the metadata of the entity type of the specified sPath Name. For each created entry a request is created and stored in a request queue. The request queue can be submitted by calling submitChanges

BackboneJS resyncing collection URL to Model after another model is destroyed

I am having an issue with persisting a collection define URL for CRUD operations after I delete a model. I have a few models, one for each contact. Currently I run a this.model.destroy when I want to delete a contact, though as soon as I destroy the model, I am getting an undefined status for the collection defined URL. Is there a way to re-establish the collection-defined URL for all other models after a destroy?
I have tried to define a rootURL, which seems to work after a deleted contact, however, if I am not deleting a contact, then I get multiple requests to send the same contact with different ID's
Here is the Delete functionality:
deleteContact: function() {
if (!this.model) {
return;
}
this.model.destroy({
success: function(model, response) {
App.Emitter.trigger('snackbar', 'Contact Deleted!', 3000);
App.Emitter.trigger('contacts:close');
App.Master.changeView('contacts');
Backbone.Collection.fetch()
// App.Contacts2.remove(this.model);
},
error: function(model, response) {
console.info('contact save error');
App.Emitter.trigger('snackbar', 'ERROR Deleting!', 3000);
}
});
},
I am getting an error:
"
app.min.js:1552 Uncaught Error: A "url" property or function must be specified"
It turns out that even though I was removing the Model, the view was sticking around in the background. The URL issue I was receiving was being thrown since it is a required field (but being thrown from a 'ghost' view that stacked up in the background). Thanks for the help.

datatables.net: Error handling for server side processing

I've setup datatables.net with server side processing on a MVC application using the DataTables.Aspnet.Core & DataTables.AspNet.WebApi2 nugets. All works well and the data gets loaded and displayed fine.
If there is an issue on the server side I catch the exception and return a result containing my custom error message:
// IDataTablesRequest tableRequest
return new DataTablesJsonResult(Response.Create(tableRequest, "my custom error message"), Request);
On the client side I've registered to the error event as well:
$.fn.dataTable.ext.errMode = 'none';
this.$dataTable.on('error.dt', this.onDataTableError.bind(this));
This also works fine, I can parse the response and check for my custom message.
Now the issue: After handling the error I always get the dreaded Uncaught TypeError: Cannot read property 'length' of undefined I assume this is the case because I don't send any data to the client?
How can I prevent this error?
I could not manage to fix this on the server side by adding an empty dataset as this would not be passed with the json.
What I ended up doing is ensuring there is always a data array on the client side:
// register to ajax request event
this.$dataTable.on('xhr.dt', this.afterAjax.bind(this));
// set empty array to make sure we have no issue
// with null references on data.length for loop
afterAjax(event: JQueryEventObject, settings: any, payload: any, response: any): void {
payload.data = payload.data || [];
}

difference between fetching page and file in serviceworker

event.respondWith(caches.match(event.request).then(function (response) {
if (response) {
return response;
}
//return fetch(event.reuqest, { credentials: 'include' });
//event.respondWith(fetch(event.request, { credentials: 'include' }));
}));
This is a common code for handling request via serviceworkers , if the url is in cache then return cache response or fetch it from server .
But my doubt is regarding the 2 commented lines , we need to use one of them for fetching the response .
My doubt is, when i use event.respondWith(fetch(event.request, { credentials: 'include' for fetching a page , i get the following error
DOMException: Failed to execute 'respondWith' on 'FetchEvent': The fetch event has already been responded to.
But the page is finally rendered , definitely browser is finally fetching the response , but when i use sam for fetching an image , i get the same error and on top of that the image is not fetched .
if i use the second option that return fetch(event.reuqest, { credentials: 'include' }); , then it works fine for both image as well as page.
I am not able to figure out what is the reason of that error , and also why it is behaving differently for file and page .
My another doubt is , do i actually need the credential parameter here ,i added it because most of the implementations i saw in web have used it,but what i have observed is that the request object already has a credential property with it , now it is not always
include
sometime it is
same-origin
too.
So could it happen that i am actually overriding the actual credential value by adding it .If that is not the case , then there is no difference in including it or not.It does not matter .
But if it is other way around , then we should not overwrite the credential value, which can have bad side effects.
You already have a call to event.respondWith, you don't need to call it twice.
Your first call is going to use the promise returned by:
caches.match(event.request).then(function(response) {
if (response) {
return response;
}
return fetch(event.reuqest, { credentials: 'include' });
})
This promise resolves to:
response, if the request is in the cache;
the promise returned by the call to fetch, otherwise.
The promise returned by fetch will resolve to a response, which is then going to be used by respondWith.

JQuery UI Autocomplete Syntax

Can someone help me understand the following code? I found it here.
It takes advantage of the JQuery UI Autocomplete with a remote source. I've commented the code as best I can and a more precise question follows it.
$( "#city" ).autocomplete({
source: function( request, response ) {
//request is an objet which contains the user input so far
// response is a callback expecting an argument with the values to autocomplete with
$.ajax({
url: "http://ws.geonames.org/searchJSON", //where is script located
dataType: "jsonp", //type of data we send the script
data: { //what data do we send the script
featureClass: "P",
style: "full",
maxRows: 12,
name_startsWith: request.term
},
success: function( data ) { //CONFUSED!
response(
$.map(
data.geonames, function( item ) {
return {
label: item.name+(item.adminName1 ? ","+item.adminName1:"")+","+item.countryName,
value: item.name
}
}
)
);
}
});
}
});
As you can see, I don't understand the use of the success function and the response callback.
I know the success function literal is an AJAX option which is called when the AJAX query returns. In this case, it seems to encapsulate a call to the response callback? Which is defined where? I thought by definition of a callback, it should be called on its own?
Thanks!
The response object as defined by the documentation ("Overview" page):
A response callback, which expects a
single argument to contain the data to
suggest to the user. This data should
be filtered based on the provided
term, and can be in any of the formats
described above for simple local data
(String-Array or Object-Array with
label/value/both properties). It's
important when providing a custom
source callback to handle errors
during the request. You must always
call the response callback even if you
encounter an error. This ensures that
the widget always has the correct
state.
so, the 'response' argument is actually a callback, which must be called upon success of the ajax retrieval of autocomplete items.
Since your data will come back via AJAX, your code must update the widget manually. jQueryUI provides an argument as a function so that your code can do that update by calling the function.
You can see the response object defined in the declaration of the function used for the source option:
source: function( request, response )
You could even take the AJAX call out of the equation and do something like this:
source: function(request, response) {
response([{label:'foo', value: 'foo'},{label:'bar', value:'bar'}]);
}
Would immediately call the response callback with an array of label/value pairs for the widget.

Resources