Kendo UI - how to implement Error Handling on WEB API, non MVC using Kendo Grid - kendo-ui

My Scenario is I created a Web API that returns an Active Directory Object.
I have this WEB API function create Active Directory User and creates a user that returns Active Directory Object that contains First Name , Last Name, Email, UserName, Etc... What If it got an error how would I handle this?
I'm using Kendo Grid InLine Edit http://demos.kendoui.com/web/grid/editing-inline.html
I want to show the error message as a pop up window
How would I do that???
Options
try catch the error and put in the Active Directory Object as
Exception???
How can I capture this is Kendo UI?
Throw the response and get the error message and show it in the Kendo Grid
//HttpResponseMessage msg = new HttpResponseMessage(HttpStatusCode.OK)
//{
// Content = new StringContent(string.Format("No User with ID = {0}.{1}", businessObject.UserName, ex.InnerException.ToString() )),
// ReasonPhrase = "CustomerID Not Found in Database!"
//};
//throw new HttpResponseException(msg);
OR
//var message = string.Format("Error Message: {0}", taskCreateADUser.ADExceptionDescription);
//throw new HttpResponseException(
// Request.CreateErrorResponse(HttpStatusCode.OK, message));
Thanks,
MarcLevin

Whenever KendoUI binds via Ajax it relies on serialized version of ModelState sent in json response. Essentially if ModelState is not valid, the json response returned to the widget (grid in this case) will contain something like this:
{
"Errors":{
"PropA":{
"errors":[
"Error1",
"Error2"
]
},
"PropB":{
"errors":[
"FUBAR"
]
}
}
}
Essentially your WebAPI will need to return similar data structure if you want the grid to respond to it.

This is regarding your Option 2. You would need to apply the following correctly to your specific scenario. This is just a sample of a really simple parse of the response and displaying an alert if an error is detected. This sample expects a JSON object containing an array of Items. You could definitely apply more advanced handling once you have the basic idea down.
$("#grid").kendoGrid({
dataSource: {
schema: {
data: function(data) {
if (data.Items[0].substring(0,37) == "allmyerrormessagesstartwiththisphrase"){
alert(data.Items[0];
} else {
return data.Items;
}
}
},
transport: {
read: "http://myurl.com/something/"
}
}
}
);

Related

How to get query sys_id of current.sys_id Service Portal (ServiceNow)

I have a question regarding a small issue that I'm having. I've created a widget that will live on the Service Portal to allow an admin to Accept or Reject requests.
The data for the widget is pulling from the Approvals (approval_approver) table. Under my GlideRecord, I have a query that checks for the state as requested. (Ex. addQuery('state', 'requested'))
To narrow down the search, I tried entering addQuery('sys_id', current.sys_id). When I use this query, my script breaks and I get an error on the Service Portal end.
Here's a sample of the GlideRecord script I've written to Accept.
[//Accept Request
if(input && input.action=="acceptApproval") {
var inRec1 = new GlideRecord('sysapproval_approver');
inRec1.addQuery('state', 'requested');
//inRec1.get('sys_id', current.sys_id);
inRec1.query();
if(inRec1.next()) {
inRec1.setValue('state', 'Approved');
inRec1.setValue('approver', gs.getUserID());
gs.addInfoMessage("Accept Approval Processed");
inRec1.update();
}
}][1]
I've research the web, tried using $sp.getParameter() as a work-around and no change.
I would really appreciate any help or insight on what I can do different to get script to work and filter the right records.
If I understand your question correctly, you are asking how to get the sysId of the sysapproval_approver record from the client-side in a widget.
Unless you have defined current elsewhere in your server script, current is undefined. Secondly, $sp.getParameter() is used to retrieve URL parameters. So unless you've included the sysId as a URL parameter, that will not get you what you are looking for.
One pattern that I've used is to pass an object to the client after the initial query that gets the list of requests.
When you're ready to send input to the server from the client, you can add relevant information to the input object. See the simplified example below. For the sake of brevity, the code below does not include error handling.
// Client-side function
approveRequest = function(sysId) {
$scope.server.get({
action: "requestApproval",
sysId: sysId
})
.then(function(response) {
console.log("Request approved");
});
};
// Server-side
var requestGr = new GlideRecord();
requestGr.addQuery("SOME_QUERY");
requestGr.query(); // Retrieve initial list of requests to display in the template
data.requests = []; // Add array of requests to data object to be passed to the client via the controller
while(requestsGr.next()) {
data.requests.push({
"number": requestsGr.getValue("number");
"state" : requestsGr.getValue("state");
"sysId" : requestsGr.getValue("sys_id");
});
}
if(input && input.action=="acceptApproval") {
var sysapprovalGr = new GlideRecord('sysapproval_approver');
if(sysapprovalGr.get(input.sysId)) {
sysapprovalGr.setValue('state', 'Approved');
sysapprovalGr.setValue('approver', gs.getUserID());
sysapprovalGr.update();
gs.addInfoMessage("Accept Approval Processed");
}
...

How to properly handle Google SDK errors in Google App Script

I am writing a google web app which uses the Admin Directory a lot. However I was wondering how the error handling should be done since I do not get a proper error object back when a request to the api fails.
Example: I want to check if a custom schema exists and if not I want to do something else:
try{
var resp = AdminDirectory.Schemas.get("129898rgv", "someCustomSchema");
}catch(err){
// if schema does not exist do this
schemaNotExistFunction();
Logger.log(err);
}
Unfortunately I do not even get the http status code back from the err. Is there another way to handle errors in Google Apps Script?
Instead of
Logger.log(error)
use
Logger.log('%s, %s',error.message, error.stack);
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error for a complete list of Error instance properties
The above because Logger.log parses the parameter as string. When you pass an error object error.name is logged, by the other hand by using
Example
Running the following code in an standalone project using the new runtime (V8) will log a couple of messages.
function myFunction() {
try{
SpreadsheetApp.getUi();
} catch (error) {
Logger.log(error);
Logger.log('%s, %s', error.message, error.stack);
}
}
Another alternative is to use console.log instead of Logger.log
function myFunction() {
try{
SpreadsheetApp.getUi();
} catch (error) {
console.log(error);
console.log('%s, %s', error.message, error.stack);
}
}

kendo ui grid filter, sort and paging in the server

I'm using kendo grid and want to perform filtering, sorting and paging in the server. I understand that I should add to the dataSource:
serverPaging: true,
serverSorting: true
But how do I tell the grid/dataSource which url it should use for the sortig, filtering etc.
And what if I want to perform the sortig myself? I want to use the control kendo provides but to go to the server myself. Is there an event like "sortTriggered" where I can call "prevntDefault" or something like that... I don't know.
Take a look at this sample. It is using the MobileServices javascript api for Windows Azure, but shows you how to handle server paging and sorting on your own.
http://jsbin.com/efeKiwO/11/edit
On the transport function of your dataSource, each method (read,update,create,destroy) can be configured to a function (this is the read function, it handles any sorting and paging).
read: function(options) {
// Get the table
var table = client.getTable("Customer");
// Build base query
var query = table.includeTotalCount();
// Add paging
if(options.data.skip !== undefined && options.data.take !== undefined) {
query = query.skip(options.data.skip).take(options.data.take);
}
// Add sorting
if(typeof options.data.sort !== "undefined" && options.data.sort !== null) {
for(var i = 0; i< options.data.sort.length; i++) {
if(options.data.sort[i].dir === "desc") {
query = query.orderByDescending(options.data.sort[i].field);
}
else {
query = query.orderBy(options.data.sort[i].field);
}
}
}
var promise = query.read();
promise.done(function(data) {
options.success(data);
});
},
Inside that function you can do whatever you like. Instead of using a javascript library like this sample, you could make a $.getJSON call, or a $.ajax call, or whatever else you want to do. The parameter object to the function will contain everything you need for paging, sorting, and filtering. Once you have the data, just call options.success(dataSet); with your properly sorting/paged dataSet and your grid will bind to it.
Your configuration is almost there,
What's missing is the secret sauce to connect to MVC.
Lets assume your DataSource configuration is like this:
var myDataSource = new kendo.data.DataSource({
transport: {
read: {
url: 'Users/Read',
type: 'POST'
}
},
serverSorting: true,
serverFiltering: true,
serverPaging: true
}
On your server side in UsersController.cs (example), you have to receive a [DataSourceRequest]
public DataSourceResult Read([DataSourceRequest] DataSourceRequest request)
{
// Here you might actually get the items from your cache or database.
var List<User> myList = new List<User>();
// Here is when the kendo magic happens.
return myList.ToDataSourceResult(request);
}
Why [DataSourceRequest] is important?
Because it contains the paging, sorting, filtering parameters that your grid is asking to the server. So if you want to do the algorithm yourself, you must examin the request and process those paramenters. Just remember to return a DataSourceResult object instance.
If your objects live in a cache and your fields need no special treatment for filtering, grouping, sorting, etc, then just use the kendo C# extension ToDataSourceResult. It will process your items and apply the filtering, sorting, paging configuration, using dynamic LINQ statements.
The Kendo grid use only one url to retrieve data and it will taken from the DataSource object.
This url will be invoked by the grid each time it will need data and the sorting and paging parameters will be added to each request made to the server base on the grid context.
The server will then receive a standard web request with the all the parameters require to build a request of your own. Then you will have to send as response properly formatted (ex: JSONP OData).

How to load image list from REST API using angularJS

I have searched in this forum for quiet a bit and here's my problem -
I have a ng-repeat in my html which takes in a list of messages(Json object).
Each message JSON has a sender email address - e.g. abc#gmail.com
Now, I have to get the email address from the message and form another REST API request to fetch their images for e.g. - http://<>:8080/getImage/abc#gmail.com (email address dynamic)
So in my code, I'll have a ng-repeat and a ng-src pointing to the image REST URL
If there's no image in server, it returns a 404 and displays a broken image on the UI. How do I handle it? On the other hand, if I make a http request to determine if there's a success message and on failure return a default image, then the whole thing goes through an endless loop. I'll try to create a fiddle and include it for better explanation.
Use the error block to handle such behavior:
function($http) {
var restUrl = 'getImage/abc';
return {
fetchImage: function(imageId) {
var self = this;
return $http.get(restUrl + '/' + imageId).
success(function(data) {
return self.imageUrl = data;
}).
error(function(data) {
return self.imageUrl = "pathToDefaultImage";
});
},
...

KendoUI datasource error event not raised on post with http 500 error

I have a datasource with error handler defined as below. In the code I am intentionally causing an error on post and the server is returning 500 plus the json data, but the error event is not being raised on post. It does fire on the read event. See http://www.ageektech.com/simplyfundraising Open your browser debugger, refresh the page, click edit change any value, click update. Need help figuring out why the error event is not triggered.
Thanks,
Dan
schema : {
model : myModel,
data : "__ENTITIES",
errors: function(e) {
debugger;
// var xhr = e.xhr;
// var statusCode = e.status;
// var errorThrown = e.errorThrown;
//alert(JSON.parse(e.responseText).error.innererror.message);
return e.errors;
}
This is not the way to subscribe to the error event of the DataSource. The schema.errors setting is used for a different purpose.
Schema.errors should contain the name of the JSON field that contains error messages.
e.g.
schema: { errors: "Errors" }
For when you are returning JSON like:
{ "Errors": "Stuff went wrong" }

Resources