wijdatasource error - javascript

Is there a way to debug or get an error when wijdatasource complete is request with a wijhttpproxy and have some problems with the data?
data: new wijdatasource({
dynamic: true,
proxy: new wijhttpproxy({
url: "#Url.Action("List")",
type: "POST",
dataType: "json"
}),
reader: {
read: function (datasource) {
alert(datasource);
var count = datasource.data.TotalRowCount;
datasource.data = datasource.data.Items;
datasource.data.totalRows = count;
new wijarrayreader([
{ name: "CdCF", mapping: "CdCF" },
{ name: "Descrizione", mapping: "Descrizione" }
]).read(datasource);
}
}
})
With the internet explorer debugger I can see the call is made with a 200 HTTP response to the List action but "alert(datasource);" is never executed.
I want to get the error that make the datasource not parse the data (if this is the error).
In a standard ajax call I could have had an "error" callback to try to debug the problem.
$.ajax({
error: function (error) {
alert("error: " + error);
},
url: '#Url.Action("List")',
success: function (code) {
var myModel = {
items: eval(code)
};
}
});

I think you want to do a Get instead of a Post.
proxy: new wijhttpproxy({
url: "#Url.Action("List")",
type: "Get",
dataType: "json"
}),

What I did is that I caught the error in the controller an modified the object I was sending back to have a "success" boolean that I checked on the read function so that if datasource.data.success was true, then I would process the data if not I would spit out a message. You would have to put everything in your controller action inside a try-catch block.

Related

JQuery confirmation dialog after AJAX request

I need to validate, on server side, if a person with a given registration number is already on the database. If this person is already registered, then I proceed with the program flow normally. But, if the number is not already registered, then I'd like to show a confirmation dialog asking if the operator wants to register a new person with the number entered and, if the operator answers yes, then the person will be registered with the number informed on the form on it's submission.
I've tried
Server side(PHP):
if (!$exists_person) {
$resp['success'] = false;
$resp['msg'] = 'Do you want to register a new person?';
echo json_encode($resp);
}
Client side:
function submit(){
var data = $('#myForm').serialize();
$.ajax({
type: 'POST'
,dataType: 'json'
,url: 'myPHP.php'
,async: 'true'
,data: data
,error: function(response){
alert('response');
}
});
return false;
}
I can't even see the alert, that's where I wanted to put my confirmation dialog, with the message written on server side. Other problem, how do I resubmit the entire form appended with the operator's answer, so the server can check if the answer was yes to register this new person?
EDIT
I was able to solve the problem this way:
Server side(PHP):
$person = find($_POST['regNo']);
if ($_POST['register_new'] === 'false' && !$person) {
$resp['exists'] = false;
$resp['msg'] = 'Do you want to register a new person?';
die(json_encode($resp)); //send response to AJAX request on the client side
} else if ($_POST['register_new'] === 'true' && !$person) {
//register new person
$person = find($_POST['regNo']);
}
if($person){
//proceed normal program flow
}
Client side:
function submit(e) {
e.preventDefault();
var data = $('#myForm').serialize();
var ajax1 = $.ajax({
type: 'POST'
, dataType: 'json'
, async: 'true'
, url: 'myPHP.php'
, data: data
, success: function (response) {
if (!response.exists && confirm(response.msg)) {
document.getElementById('register_new').value = 'true'; //hidden input
dados = $('#myForm').serialize(); //reserialize with new data
var ajax2 = $.ajax({
type: 'POST'
, dataType: 'json'
, async: 'true'
, url: 'myPHP.php'
, data: data
, success: function () {
document.getElementById('register_new').value = 'false';
$('#myForm').unbind('submit').submit();
}
});
} else if (response.success) {
alert(response.msg);
$('#myForm').unbind('submit').submit();
}
}
});
}
There doesn't appear to be anything wrong with your PHP.
The problem is (1) You are doing the alert inside of an error callback, and your request isn't failing, so you don't see the alert. (2) You are alerting the string 'response' instead of the variable response.
It is also worth noting that you should be using the .done() and .fail() promise methods (http://api.jquery.com/jquery.ajax/#jqXHR).
Here is the fixed JS:
function submit() {
var data = $('#myForm').serialize();
// Same as before, with the error callback removed
var myAjaxRequest = $.ajax({
type: 'POST',
dataType: 'json',
url: 'myPHP.php',
async: 'true',
data: data
});
// The request was successful (200)
myAjaxRequest.done(function(data, textStatus, jqXHR) {
// The data variable will contain your JSON from the server
console.log(data);
// Use a confirmation dialog to ask the user your question
// sent from the server
if (confirm(data.msg)) {
// Perform another AJAX request
}
});
// The request failed (40X)
myAjaxRequest.fail(function(jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
});
return false;
}
Also, you are setting a 'status' in PHP and checking that in the JS (I presume). What you want to be doing is setting a HTTP status code from the server, as below:
if (!$exists_person)
{
$resp['msg'] = 'Do you want to register a new person?';
// 400 - Bad Request
http_response_code(400);
echo json_enconde($resp);
}
Then, jQuery will determine whether the request failed based on the status code you respond with. 200 is a successful request, and 400 numbers are fail.
Check out this page for a full list: https://httpstatuses.com/
Okay so this is a two part question; I'll try my best to answer both parts:
Part 1: How to detect if success is false and trigger the confirmation popup?
In jQuery.ajax the error handler is triggered based on response code. This is probably not what you want. You can use your success handler and test the value res.success to see if it's true or false. It would be something along the lines of:
function submit(e) {
e.preventDefault();
var data = $('#myForm').serialize();
$.ajax({
type: 'POST',
dataType: 'json',
url: 'myPHP.php',
async: 'true',
data: data
}).done(function(res) {
if (!res.success) {
alert(res.msg);
}
});
}
Part 2: How do I resubmit with a confirmation?
Working off of our previous code we will make some changes that allow for submit() to be passed an argument registerNew. If registerNew is true we will pass it as a param to the ajax handler in the PHP so it knows we want to register a new person. The Javascript will look something like this:
function submit(e, registerNew) {
if (e) e.preventDefault();
var data = $('#myForm').serialize();
var ajax_options = {
type: 'POST',
dataType: 'json',
url: 'myPHP.php',
async: 'true',
data: data
};
ajax_options.data.register_new = !!registerNew;
$.ajax(ajax_options).done(function(res) {
if (!res.success && confirm(res.msg)) {
submit(null, true);
}
});
}
As you can see here, we are passing a new register_new param in the data in our ajax options. Now we need to detect this on the PHP side, which is easy enough and looks like this (this goes in your php ajax handler):
if ($_POST["register_new"]) {
// new user registration code goes here
} else {
// your existing ajax handler code
}
Add confirm inside submit function
function submit(){
var data = $('#myForm').serialize();
if (confirm('Are you ready?')) {
$.ajax({
type: 'POST'
,dataType: 'json'
,url: 'myPHP.php'
,async: 'true'
,data: data
,error: function(response){
alert('response');
}
});
}
return false;
}

JSON object is undefined in ajax call

In my Django project I'm trying to create a page that constantly displays the current state of a certain field in a database. I'm using ajax to do that but for reason the response object I'm returning keeps coming back as undefined.
Here is my view:
def call_ajax(request):
if request.is_ajax():
userp = UserProfile.objects.get(user=request.user)
accepted = userp.recent_call.accepted
hello = "hello"
ajax_vars = {
'accepted':accepted,
'hello':hello,
}
return JsonResponse(ajax_vars)
Here is the relevant javascript:
$(document).ready(function(response){
ajax_call(response);
});
function ajax_call(response){
$.ajax({
type: 'GET',
url: '/calls/call_ajax/',
dataType: 'json',
async: true,
data: {
accepted: response.accepted,
hello: response.hello,
},
success: function(response) {
console.log(response.hello)
$('#info').html('<p>'+response.hello+'</p>');
},
error: function() {
$('#info').html('<p>An error has occurred</p>');
}
});
setInterval(function() { ajax_call(response); },10000)
}
For some reason the console is logging that the response object is undefined. Any tips?

HttpClient PostAsync equivalent in JQuery with FormURLEncodedContent instead of JSON

I wrote a JQuery script to do a user login POST (tried to do what I have done with C# in the additional information section, see below).
After firing a POST with the JQuery code from my html page, I found the following problems:
1 - I debugged into the server side code, and I know that the POST is received by the server (in ValidateClientAuthentication() function, but not in GrantResourceOwnerCredentials() function).
2 - Also, on the server side, I could not find any sign of the username and password, that should have been posted with postdata. Whereas, with the user-side C# code, when I debugged into the server-side C# code, I could see those values in the context variable. I think, this is the whole source of problems.
3 - The JQuery code calls function getFail().
? - I would like to know, what is this JQuery code doing differently than the C# user side code below, and how do I fix it, so they do the same job?
(My guess: is that JSON.stringify and FormURLEncodedContent do something different)
JQuery/Javascript code:
function logIn() {
var postdata = JSON.stringify(
{
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
});
try {
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: postdata,
dataType: "json",
success: getSuccess,
error: getFail
});
} catch (e) {
alert('Error in logIn');
alert(e);
}
function getSuccess(data, textStatus, jqXHR) {
alert('getSuccess in logIn');
alert(data.Response);
};
function getFail(jqXHR, textStatus, errorThrown) {
alert('getFail in logIn');
alert(jqXHR.status); // prints 0
alert(textStatus); // prints error
alert(errorThrown); // prints empty
};
};
Server-side handling POST (C#):
public override async Task ValidateClientAuthentication(
OAuthValidateClientAuthenticationContext context)
{
// after this line, GrantResourceOwnerCredentials should be called, but it is not.
await Task.FromResult(context.Validated());
}
public override async Task GrantResourceOwnerCredentials(
OAuthGrantResourceOwnerCredentialsContext context)
{
var manager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var user = await manager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError(
"invalid_grant", "The user name or password is incorrect.");
context.Rejected();
return;
}
// Add claims associated with this user to the ClaimsIdentity object:
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
foreach (var userClaim in user.Claims)
{
identity.AddClaim(new Claim(userClaim.ClaimType, userClaim.ClaimValue));
}
context.Validated(identity);
}
Additional information: In a C# client-side test application for my C# Owin web server, I have the following code to do the POST (works correctly):
User-side POST (C#):
//...
HttpResponseMessage response;
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>( "grant_type", "password"),
new KeyValuePair<string, string>( "username", userName ),
new KeyValuePair<string, string> ( "password", password )
};
var content = new FormUrlEncodedContent(pairs);
using (var client = new HttpClient())
{
var tokenEndpoint = new Uri(new Uri(_hostUri), "Token"); //_hostUri = http://localhost:8080/Token
response = await client.PostAsync(tokenEndpoint, content);
}
//...
Unfortunately, dataType controls what jQuery expects the returned data to be, not what data is. To set the content type of the request data (data), you use contentType: "json" instead. (More in the documentation.)
var postdata = JSON.stringify(
{
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
});
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: postdata,
dataType: "json",
contentType: "json", // <=== Added
success: getSuccess,
error: getFail
});
If you weren't trying to send JSON, but instead wanted to send the usual URI-encoded form data, you wouldn't use JSON.stringify at all and would just give the object to jQuery's ajax directly; jQuery will then create the URI-encoded form.
try {
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: {
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
},
dataType: "json",
success: getSuccess,
error: getFail
});
// ...
To add to T.J.'s answer just a bit, another reason that sending JSON to the /token endpoint didn't work is simply that it does not support JSON.
Even if you set $.ajax's contentType option to application/json, like you would to send JSON data to MVC or Web API, /token won't accept that payload. It only supports form URLencoded pairs (e.g. username=dave&password=hunter2). $.ajax does that encoding for you automatically if you pass an object to its data option, like your postdata variable if it hadn't been JSON stringified.
Also, you must remember to include the grant_type=password parameter along with your request (as your PostAsync() code does). The /token endpoint will respond with an "invalid grant type" error otherwise, even if the username and password are actually correct.
You should use jquery's $.param to urlencode the data when sending the form data . AngularJs' $http method currently does not do this.
Like
var loginData = {
grant_type: 'password',
username: $scope.loginForm.email,
password: $scope.loginForm.password
};
$auth.submitLogin($.param(loginData))
.then(function (resp) {
alert("Login Success"); // handle success response
})
.catch(function (resp) {
alert("Login Failed"); // handle error response
});
Since angularjs 1.4 this is pretty trivial with the $httpParamSerializerJQLike:
.controller('myCtrl', function($http, $httpParamSerializerJQLike) {
$http({
method: 'POST',
url: baseUrl,
data: $httpParamSerializerJQLike({
"user":{
"email":"wahxxx#gmail.com",
"password":"123456"
}
}),
headers:
'Content-Type': 'application/x-www-form-urlencoded'
})
})

JSON pass null value to MVC 4 controller in IE9

I got some problem while posting JSON data into MVC 4 controller.
Below method is working fine in Firefox but unfortunately failed in IE 9
The JavaScript :
var newCustomer = {
CustName: $("#CustName").val(),
CustLocalName: $("#CustLocalName").val(),
CustNumber: $("#CustNumber").val(),
CountryID: $("#SelectCountry").val(),
City: $("#City").val()
};
$.ajax({
url: '#Url.Content("~/CustomerHeader/CreateCustomerHeader")',
cache: false,
type: "POST",
dataType: "json",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(newCustomer),
success: function (mydata) {
$("#message").html("Success");
},
error: function () {
$("#message").html("Save failed");
}
});
and this is my controller :
public JsonResult CreateCustomerHeader(CustomerHeader record)
{
try
{
if (!ModelState.IsValid)
{
return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
}
RepositoryHeader.Update(record);
return Json(new { Result = "OK", Record = record});
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
the "data" variable as in public JsonResult CreateCustomerHeader(CustomerHeader **data**) is getting NULL but while using FireFox it holds the correct value.
UPDATE : New method trying using $.post
function CreateNewCustomer(newCustomer) {
$.post("/CustomerHeader/CreateCustomerHeader",
newCustomer,
function (response, status, jqxhr) {
console.log(response.toString())
});
}
Based off the bit that you've shown, this is a simplified variation that may work more consistently, using jQuery.post() (http://api.jquery.com/jQuery.post/):
var data = {
CustName: $("#CustName").val(),
CustLocalName: $("#CustLocalName").val(),
CustNumber: $("#CustNumber").val(),
CountryID: $("#SelectCountry").val(),
City: $("#City").val()
};
$.post({
'#Url.Action("CreateCustomerHeader", "CustomerHeader")',
data,
function(response, status, jqxhr){
// do something with the response data
}).success(function () {
$("#message").html("Success");
}).error(function () {
$("#message").html("Save failed");
});
$.post() uses $.ajax as it's base, but abstracts some of the details away. For instance, $.post calls are not cached, so you don't need to set the cache state (and setting it is ignored if you do). Using a simple JavaScript object lets jQuery decide how to serialize the POST variables; when using this format, I rarely have issues with the model binder not being able to properly bind to my .NET classes.
response is whatever you send back from the controller; in your case, a JSON object. status is a simple text value like success or error, and jqxhr is a jQuery XMLHttpRequest object, which you could use to get some more information about the request, but I rarely find a need for it.
first of all I would like to apologize #Tieson.T for not providing details on JavaScript section of the view. The problem is actually caused by $('#addCustomerHeaderModal').modal('hide') that occurred just after ajax call.
The full script :
try{ ..
var newCustomer =
{
CustName: $("#CustName").val(),
CustLocalName: $("#CustLocalName").val(),
CustNumber: $("#CustNumber").val(),
CountryID: $("#SelectCountry").val(),
City: $("#City").val()
};
$.ajax({
url: '/CustomerHeader/CreateCustomerHeader',
cache: false,
type: "POST",
dataType: "json",
data: JSON.stringify(newCustomer),
contentType: "application/json; charset=utf-8",
success: function (mydata) {
$("#message").html("Success");
},
error: function () {
$("#message").html("Save failed");
}
});
}
catch(Error) {
console.log(Error.toString());
}
//$('#addCustomerHeaderModal').modal('hide')//THIS is the part that causing controller cannot retrieve the data but happened only with IE!
I have commented $('#addCustomerHeaderModal').modal('hide') and now the value received by controller is no more NULL with IE. Don't know why modal-hide event behave like this with IE9.
Thanks for all the efforts in solving my problem guys :-)

ExtJS store initialization using json fails

I have a store like this:
Ext.define('app.store.System', {
extend : 'Ext.data.Store',
model : 'app.model.System',
autoLoad: true,
autoSync: true,
proxy: {
type: 'rest',
format: 'json',
url: '/application/appinfo',
method : "GET",
reader: {
type: 'json',
root: 'System'
},
writer: {
root: 'System',
allowSingle: false
}
}
});
and I have a service endpoint to handle requests that match /application with this method:
#GET
#Path("/{sysinfo}")
public List<SystemInfo> getSystemInfo() {
if(sysinfo == null){
sysinfo = new SystemInfo();
...initialize
}
List<SystemInfo> resultList = new ArrayList<SystemInfo>();
resultList.add(sysinfo);
return resultList;
}
and it seemed to work... when I tried to to reach localhost:port/application/sysinfo.json I got this:
{ [{"address":"...","feeds":["feed1","feed2"] } ] }
which seems correct but when I try to read the data from the store in the view's init method:
var store = Ext.StoreManager.lookup('System');
var data = [];
store.each(function(record) {
data.push(record.getData());
console.log("record data: ");
console.log(record.getData());
});
console.log(data[0]);
It says that it's undefined as if the store was empty. I tried it with the debugger and i found that the getSystemInfo() was called after the view's initcomponent but unfortunately I don't know why that is or how to solve it. Any ideas?
Thanks for your time.
Have you tried loading your store first?
var store = Ext.StoreManager.lookup('System');
var data = [];
store.load({
callback: function(storeVar, records, successful) {
Ext.each(records, function(record) {
data.push(record.getData());
console.log("record data: ");
console.log(record.getData());
});
}
console.log(data[0]);
});
And what boris says is true, you need to define your root property in the returned JSON.
If you're using chrome or firefox you can also check which network call is made, and what it returns (JSON data...).
Try this:
return new { success: true, System = resultList};

Categories