Grails: data from Ajax call not shown in params variable in Controller - ajax

I have to make an ajax call to deliever some data. The strange thing is that the data apperently will not be transmitted to the action in the controller:
this is my ajax call:
var params = [id: "3", version: "58", selected: "true", format: "json"]
$.ajax({
type: "POST",
cache: false,
url: "/selection/ajaxUpdate",
dataType: 'json',
data: params,
success:function(data,textStatus){
console.log("success: ",data)
},
error:function(XMLHttpRequest,textStatus,errorThrown){
console.log("error: ",XMLHttpRequest)
}
});
this is my action in controller "selection":
#Transactional
def ajaxUpdate(){
println params
.... other stuff ...
}
The println params command just outputs: "[controller:selection, format:null, action:ajaxUpdate]"
Because of the println the action is obviously called, but without the ajax params :(
Does anyone know a solution?
Thx in advance

You need to tell Grails action to accept JSON params
#Transactional
def ajaxUpdate(){
def jsonParams = request.JSON
println jsonParams // this will print the ajax params
println params
.... other stuff ...
}

vahid is right: what a dumb js mistake. Of course i need to setup the params as a json-object {} instead of an array []. So this one works:
{id: "3", version: "58", selected: "true", format: "json"}

Related

DataTables Editor In MVC

I want to use DataTables Editor but I want full control over the post back rather than letting Editor-Server handle it. Is there a way to do this? I am able to specifiy the url in Ajax on the client side and it does post back to the Controller, the only problem is I cannot figure how to get the data out of the call.
This is the Ajax portion:
$(document).ready(function () {
editor = new $.fn.dataTable.Editor({
ajax: ({
url: "/../AnyController/Update",
dataType: "json",
contentType: "application/json",
type: 'POST'
}),
formOptions: {
inline: {
onBlur: true,
submit: 'all'
}
},
table: "#timetracker",
fields: [
{
label: "Date1:",
name: "Date1"
},
{
label: "Comment 1:",
name: "Comment1",
type: "textarea"
}
]
});
And this is the Contoller method:
[HttpPost]
public JsonResult Update(EditorReturnData wtd)
{
return Json(wtd);
}
I have tried using a variety of other method signatures but the value of wtd is always null. I have no problem loading the table just by passing Json data, but how to takeover the update process from datatables editor is eluding me.
I have one update. I could not figure out how the Get, Post and Put could all use the same Controller Method and the method takes no parameters, even for the Post and Put. Finally I figured out that Editor is passing the data in the Header and it could be accessed with Request.Body. From there it must be the Datatables dll that is doing the actual updates.
enter code hereI have found the best way to do this is to post back from ajax to a different Controller for Post and Put and you can get access to the return data from the HttpRequest body in the following manner.
public ActionResult Rest(HttpRequest request)
{
var stream = request.Body;
string url = new StreamReader(stream).ReadToEnd();
string newUrl;
while ((newUrl = Uri.UnescapeDataString(url)) != url)
url = newUrl;
I added this code to the RestController from the Datatables Dot Net Core Demo Rest example which can be downloaded from https://editor.datatables.net/
The Ajax looks like this
editor = new $.fn.dataTable.Editor( {
ajax: {
create: {
type: 'POST',
url: '/api/rest/create'
},
edit: {
type: 'PUT',
url: '/api/rest/edit'
},
remove: {
type: 'DELETE',
url: '/api/rest/remove'
}
},

Django Ajax 'GET'

newbie here. I am trying to get some data from my database using ajax.
In my views.py,
def getEvents(request):
eventList = Events.objects.all()
events=[]
for event in eventList:
events.append({"name": event.name, "start": event.start, "end": event.end})
return HttpResponse(events, content_type="application/json")
Note that Events is the model that I am trying to parse. After I collect the data from this model, I want to return it to my template using the following ajax code:
$.ajax({
url: 'getEvents/',
datatype: 'json',
type: 'GET',
sucess: function(data) {
alert(data.name);
}
});
In my urls.py:
url(r'^getEvents/', views.getEvents, name='getEvents'),
However, I think I am doing something wrong because it doesn't work. I have been stuck on this for hours...Any ideas?
EDIT:
Okay. When I append the getEvents to the url, I do see all the database objects together in a dict but it seems my ajax is not working. How do I parse this data? The data is in the form:
[{"start": "2017-02-06", "end": "2017-02-07", "name": "Capstone Meeting"},
{"start": "2017-02-07T0:00", "end": "2017-02-08", "name": "Capstone"},
{"start": "2017-01-31T0:00", "end": "2017-02-01", "name": "dasdsd"},
{"start": "2017-01-31", "end": "2017-02-01", "name": "hjb"}]
Here is what I have so far...
$.ajax({
url: 'getEvents/',
datatype: 'json',
type: 'GET',
sucess: function(data) {
$.each(data, function(index, element) {
$('body').append($('<div>', {
text: element.name
}));
});
}
});
One of your errors is being caused by not using a JsonResponse in your view instead of an HttpResponse. Here’s how to fix that issue:
from django.http import JsonResponse
def getEvents(request):
eventList = Events.objects.all()
events=[]
for event in eventList:
events.append({"name": event.name, "start": event.start, "end": event.end})
return JsonResponse(events)
From the docs, the JsonResponse is
An HttpResponse subclass that helps to create a JSON-encoded response.
The reason that your regular HttpResponse didn’t work, is because you have to manually serialize the data to JSON when using an HttpResponse, e.g., something like:
import json
response_data = json.dumps(events)
return HttpResponse(response_data, content_type="application/json")
Otherwise, I think what will happen is that you will get a call to __repr__ on the events list which will get you python ast serialized data and not JSON serialized data.
First of all, there's a typo of your sucess function, it should be success.
Secondly, JSON response should be a dict object rather than a list, if you really want to get a JSON array response anyway, then you have to specify safe=False when you serializing the data by using JsonResponse(events, safe=False), otherwise you'll get a TypeError like TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False.
So the code sample should be:
def getEvents(request):
eventList = Events.objects.all().values("name", "start", "end")
return JsonResponse({"events": eventList})
And for frontend:
$.ajax({
url: 'getEvents/',
datatype: 'json',
type: 'GET',
success: function(data) {
$.each(data.events, function(index, element) {
$('body').append($('<div>', {
text: element.name
}));
});
}
});

QUnit testing: how to test the response of an Ajax call within a method?

so I want to test a method called 'getTheValues', which makes an Ajax call. I've mocked the server response with the values but when I run the test I get two failures but no explanation of why they failed. What am I doing wrong here?
test("Test - call Ajax within method.", function () {
var callback = sandbox.spy();
server.respondWith("GET", "/ajaxtest/getmethod",
[200, { "Content-Type": "application/json" },
'[{ "id": 123, "name": "John" }]']);
getTheValues();
server.respond();
ok(callback.calledOnce, "Callback was called once");
ok(callback.calledWith([{ id: 123, name: "John" }]), "Callback with correct values.");
});
function getTheValues(callback) {
// do some stuff including an ajax call:
$.ajax({
type: 'GET',
dataType: 'json',
cache: false,
url: '/ajaxtest/getmethod',
success: function(data) {
} });
}
first the (working) code:
QUnit.module('Test Module', {
before: function () {
this.server = sinon.fakeServer.create();
},
after: function () {
this.server.restore();
delete this.server;
}
});
QUnit.test("Test - call Ajax within method.", function (assert) {
var callback = sinon.spy(jQuery, "ajax");
this.server.respondWith("GET", "/ajaxtest/getmethod", /*?id=123&name=-John*/
[200, { "Content-Type": "application/json" },
'[{ "id": 123, "name": "John" }]']);
var a = getTheValues();
this.server.respond();
assert.ok(callback.calledOnce, "Callback was called once");
var callArgs = callback.args[0][0];
assert.equal(JSON.stringify(callArgs.data), JSON.stringify({ "id": 123, "name": "John" }));
});
function getTheValues() {
// do some stuff including an ajax call:
$.ajax({
data: { id: 123, name: "John" },
method: 'GET',
dataType: 'json',
cache: false,
url: '/ajaxtest/getmethod',
success: function (data) {
}
});
next explanations
this seems to me this is not pure QUnit test. I assume you're using SinonJS as well.
on the spy method you need to point what will be spied
sinon.spy(jQuery, "ajax")
you cannot use callback.calledWith like this for it returns true/false and comparing objects ({}==={}) will (almost) always return false. So this test will constantly fail. Instead you need spy arguments (in your case callback.args[0][0];) and compare particular part with desired result. More about this you could find here
Actually you do not need to extract those but I did it to make code (hopefully) more clear.
So
1st extract arguments,
next strignify objects to be comparable
without any other code and
then use equal method to compare with
expected values
And finally your mock object lacks data object with will be send along with the GET request.
HTH

Ajax "GET" not working in IE 8

The following code is not working in IE8, I have to get data from my controller and need to access the function abcd() and do something, my breakpoint comes out directly without going inside the ajaxcall
$.ajax({
url: "/Transactions/MyList/" + transactionID,
type: "GET",
contentType: "application/json",
cache: false,
success: abcd
});
**function abcd()** {
//do something
}
$.get( "//here give the id/class" );
For example:
$.get( "test.php" );
or
$.get( "test.php", { name: "abc", time: "2pm" } ); etc
I would guess that MyList is an action method inside TransactionsController and it returns JsonResult. Correct? Do you AllowGet on your Json result? you can pass a second parameter to the Json result which indicates the AllowGet behaviour (return Json(data, JsonRequestBehavior.AllowGet))...
Plus your abcd method should have one parameter - data - to process what you receive from the call...

Extjs 4.2: How to send parameters properly in a Ext.Ajax.Request POST

I have to do a POST from my ExtJs script in order to delete something from my DB:
Ext.Ajax.request({
url: 'deleteRole.html',
method: 'POST',
headers: {'Content-Type': 'text/html'},
waitTitle: 'Connecting',
waitMsg: 'Sending data...',
params: {
"rolename" : rolename
},
scope:this,
success: received,
failure: function(){console.log('failure');}
});
when the post is sent i can see in the firebug the rolename in font but not as a param. I would like to show you another post (made with spring:form) relative to the user registration. If i inspect the post i can see the following:
(source: subirimagenes.com)
And i can get the parameters in my controller using #RequestParam.
But in the post that i have problems i can't see the parameters part, i can only see the Font(Fuente) part:
(source: subirimagenes.com)
As a consequence, my spring controller does not detect any parameter. Is it something wrong in my POST?
Thank you
The problem is that you are using the line headers: {'Content-Type': 'text/html'}, in your original question. This would set the content to text/html instead of the content being post data.
I solved it with the following code:
var rolename = 'myRol';
Ext.Ajax.request({
url: 'deleteRole.html',
method: 'POST',
params: {
rolename: rolename
},
success: received,
failure: function(){console.log('failure');}
});
I'm using this in a Sencha Touch app. I had to add an extra config called jsonData and make it true or else nothing is passed to my endpoint url.
Ext.Ajax.request({
url: endpoint,
method : "POST",
headers: {
'Content-Type': 'application/json'
},
params : {add: formattedAddress, lat: latitude},
jsonData: true,
useDefaultXhrHeader : false,
withCredentials: true,
success : function(response) {
Ext.Msg.alert("Success", 'yea');
},
failure : function(response) {
var respObj = Ext.JSON.decode(response.responseText);
Ext.Msg.alert("Error", respObj.status.statusMessage);
}
});

Resources