Error when doing ajax with grails and javascript - javascript

I have this jquery function on the client side...
$('#add-car').on('click', function() {
$.ajax({
type: 'POST',
url: 'cars/',
data: {brand: 'brand', model: 'model', price: 100,
registryYear:1999},
success: function(data) { console.log(data)},
dataType: 'json'
});
});
And this Grails code in the server side
class UrlMappings {
static mappings = {
"/cars/$id?"(controller: "cars") {
action = [GET:"list", POST:"save", DELETE:"delete", PUT:"edit"]
}
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
}
import grails.converters.JSON
class CarsController {
def index() {
render ( Car.findAll() as JSON )
}
def save() {
def json = request.JSON
def car = new Car(json)
car.save()
render (json)
}
def delete() {
def car = Car.findById(params.id)
car?.delete()
render (car as JSON)
}
def edit() {
def car = Car.findById(params.id)
bindData(car, request.JSON)
render (car.save() as JSON)
}
}
But when the button #add-car is pressed it returns nothing... What Am I doing wrong?

This is about debugging method.
Please check if the request comes to your server or not. You can do that by adding some logs "Running here" into your requested action at the controller.
If the "Running here" get printed, the request was sent and you must find out how the server doesn't return the expected result.
If the log doesn't get printed, it means you must re-check your javascript. Using Firebug may help in uncovering some tricky javascript bugs.
By the way, I think you should use "jQuery" instead of "$" sign in your javascript. That is for avoiding conflicts with other libraries, such as:
jQuery('#add-car').click(function() {
....
});

well i dont code in grails
but your closest url mapping appears to be this "/cars/$id?"
which im assuming requires an ID
but from your javascript code you are not sending back any variable named Id

Related

How to make loop function using multiple input value to JSL in Groovy

I'm using the below function in Jenkins Shared Library.
/* The below function delete uploads that exist in the server. */
def delete_upload(server_url,each_upload_id,authentication){
def delete_upload_url = server_url + "/api/v1/uploads/" + each_upload_id
def response = httpRequest consoleLogResponseBody: true,
contentType: 'APPLICATION_JSON',
customHeaders: [[maskValue: false, name: 'id ', value: each_upload_id],
[maskValue: false, name: 'Authorization', value: authentication]],
httpMode: 'DELETE', ignoreSslErrors: true, responseHandle: 'NONE', url: delete_upload_url,
validResponseCodes: '100:599'
if(response.status == 202){
def result = readJSON text: """${response.content}"""
return result['message'].toString()
}
else {
throw new Exception("Incorrect upload id! Please give the correct upload id.")
}
}
====================================================================================================
I'm getting below response,
Response Code: HTTP/1.1 202 Accepted
Response:
{"code":202,"message":"Delete Job for file with id 2","type":"INFO"}
Success: Status code 202 is in the accepted range: 100:599
====================================================================================================
Purpose: I'm using the above JSL function to delete a uploads in the web server using upload id.
Requirement:
I need to delete multiple uploads by using multiple upload id's (like each_upload_id in 1,2,3 etc) using this JSL delete function.
Need to pass the upload id's in loops and delete the uploads in the web server.
Any suggestions, please ?
Are you looking for something like this?
def idList = ["1", "2", "3"]
try {
idList.each{ id =>
delete_upload(server_url,id,authentication)
}
} catch(e) {
println "Error occurred!"
}

How to retrieve post data from view of django app

All I am new to jquery and Django.
I used the following code to post when the button with id 'submit_data' is clicked. Is it possible to retrieve the dictionary { data_key: 'myString'} from the views.py of the Django app?
If yes how?
$(function() {
$('#submit_data').on('click',function() {
$.post('/url/', { data_key: 'myString'}, function(result) {
alert('successfully posted');
});
});
});
For a POST request with form data, you can use request.POST:
def my_view(request):
print(request.POST)
# ...
For a POST request with JSON data, you need to decode request.body:
import json
def my_view(request):
# TODO: missing a suitable `content-type` header check
data = json.loads(request.body.decode())
print(data)
# ...
request.data is used to fetch data from your frontend
it is a dictionary-like object that lets you access submitted data by key name.
Try this:
request.data.get('data_key',None).
To avoid KeyError, you can use .get() which provides value if key found else None is returned.
In template script
$(function() {
$('#submit_data').on('click',function() {
$.post('/url/', { 'data_key': 'myString'}, function(result) {
alert('successfully posted');
});
});
});
in views.py
if request.method == 'POST':
data = request.POST.get('data_key', None)

Cannot get response content in mithril

I've been trying to make a request to a NodeJS API. For the client, I am using the Mithril framework. I used their first example to make the request and obtain data:
var Model = {
getAll: function() {
return m.request({method: "GET", url: "http://localhost:3000/store/all"});
}
};
var Component = {
controller: function() {
var stores = Model.getAll();
alert(stores); // The alert box shows exactly this: function (){return arguments.length&&(a=arguments[0]),a}
alert(stores()); // Alert box: undefined
},
view: function(controller) {
...
}
};
After running this I noticed through Chrome Developer Tools that the API is responding correctly with the following:
[{"name":"Mike"},{"name":"Zeza"}]
I can't find a way to obtain this data into the controller. They mentioned that using this method, the var may hold undefined until the request is completed, so I followed the next example by adding:
var stores = m.prop([]);
Before the model and changing the request to:
return m.request({method: "GET", url: "http://localhost:3000/store/all"}).then(stores);
I might be doing something wrong because I get the same result.
The objective is to get the data from the response and send it to the view to iterate.
Explanation:
m.request is a function, m.request.then() too, that is why "store" value is:
"function (){return arguments.length&&(a=arguments[0]),a}"
"stores()" is undefined, because you do an async ajax request, so you cannot get the result immediately, need to wait a bit. If you try to run "stores()" after some delay, your data will be there. That is why you basically need promises("then" feature). Function that is passed as a parameter of "then(param)" is executed when response is ready.
Working sample:
You can start playing with this sample, and implement what you need:
var Model = {
getAll: function() {
return m.request({method: "GET", url: "http://www.w3schools.com/angular/customers.php"});
}
};
var Component = {
controller: function() {
var records = Model.getAll();
return {
records: records
}
},
view: function(ctrl) {
return m("div", [
ctrl.records().records.map(function(record) {
return m("div", record.Name);
})
]);
}
};
m.mount(document.body, Component);
If you have more questions, feel free to ask here.

Ajax through javascript route, controller should return json and return html page

Environment : scala 2.10, play 2.1.1, eclipse 4.2
Use case : the user click on a link figuring an object (game) in the database. An ajax request is sent through Javascript Route to a controller, which load the game data, convert it to json and send it back to view. The ajax success callback print the game title into a div.
Problem: i dont get a json, but the a html page (the page from which the ajax request s sent).
I suspect the problem is in the router : i put a print("route") in the javascript route action and a print("load game") in load game action. The "route" is displayed in console, but not the "load game". It may also come from my loadGame(id) route, but i dont see how i should set it.
Here is my code.
Routes:
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Home page
GET / controllers.Application.index
# Javascript routes
GET /javascriptRoutes controllers.Application.javascriptRoutes
# Library
GET /library/:id controllers.UserController.library(id: Long)
GET /library/:id controllers.GameController.loadGame(id: Long)
View:
<div class="span2">
<ul class="nav nav-pills nav-stacked">
#userGames.map { game =>
<li>#game.title</li>
}
</ul>
</div>
...
<script>
var successFn = function(data) {
$('#gameInfo').html('');
$("#gameInfo").append('<h4>'+data.title+'</h4>')
}
var errorFn = function(err) {
console.debug("Error of ajax Call");
console.debug(err);
}
ajax1 = {
dataType: 'text',
contentType:'application/json',
success: successFn,
error: errorFn
}
var displayGameInfo = function(id) {
javascriptRoutes.controllers.GameController.loadGame(id)
.ajax(ajax1);
}
</script>
ApplicationController with javascript route:
...
object Application extends Controller {
def javascriptRoutes = Action { implicit request =>
import routes.javascript._
println("-=== route ===-")
Ok(
Routes.javascriptRouter("javascriptRoutes")(routes.javascript.GameController.loadGame)
).as("text/javascript")
}
}
GameController with loadGame(id) method:
object GameController extends Controller {
...
// Library
def loadGame(id: Long) = Action(parse.json) { implicit request =>
println("-=== load game ===-")
val mess = Json.toJson(Game.find(id))
Ok(mess)
}
}
Game model:
case class Game(id: Long, title: String, description: String, userId: Long)
object Game {
val game = {
get[Long]("id") ~
get[String]("title") ~
get[String]("description") ~
get[Long]("userId") map {
case id~title~description~userId => Game(id, title, description, userId)
}
}
...
def find(id: Long): Game = DB.withConnection { implicit c =>
SQL("select * from game where id = {id}")
.on('id -> id).as(game *).head
}
implicit object GameFormat extends Format[Game] {
def reads(json: JsValue) = JsSuccess(Game(
(json \ "id").as[Long],
(json \ "title").as[String],
(json \ "description").as[String],
(json \ "uid").as[Long]
))
def writes(game: Game) = JsObject(Seq(
"id" -> JsNumber(game.id),
"title" -> JsString(game.title),
"description" -> JsString(game.description),
"userId" -> JsNumber(game.userId))
)
}
}
In your routes file, you have to routes matching the same URL :
# Library
GET /library/:id controllers.UserController.library(id: Long)
GET /library/:id controllers.GameController.loadGame(id: Long)
When your browser request the /library/123 url, Play will try the routes in the order of declaration and will match the first one, calling the controllers.UserController.library() Action. This is probably why you get a full HMTL page.
Try to define a different URL for the second route (the one returning JSON) and Play will be able to match the correct Action.
Ex :
GET /library/:id controllers.UserController.library(id: Long)
GET /gameData/:id controllers.GameController.loadGame(id: Long)

Is there a way to send an object as well as a separate variable in an ajax POST request

I have a post request I am doing like so:
var addProject = function (project, id) {
return $.ajax(projectUrl, {
type: "POST",
data: { project: project, id: id }
});
};
This is all fine, and it send up my project object (in JSON) with no problem. What i want to do is this request but also add in a key (that does not belong in the project object) that I can pass to the server controller. Any idea if I can do this, or what is a good way to do this. I really don't want to have to go back and change my object models to account for a key that I will only need every once in awhile.
This is an ASP.NET MVC4 project, and it is going back to a web api controller if that matters.
EDIT: here is my server side stuff
public HttpResponseMessage PostNew(Project project, int id)
{
//TODO grab the client to add the project to
Uow.Projects.Add(project);
Uow.Commit();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, project);
//response.Headers.Location = new Uri(Url.Link("ApiControllerAction", new { id = client.ID }));
return response;
}
Maybe I am not being clear enough. I want to pass in the project object, and then just an int variable. Passing project alone works, but if I try to pass the int it gives me a 400 error
var addProject = function (project) {
return
$.ajax(projectUrl, {
type: "POST",
data: {data1 : 'Object',data2: 'variable'}
});
};
You have just to send 2 data params., object and var..
Easiest way to pass a complex object is to JSON-encode it:
var addProject = function (project) {
return $.ajax(projectUrl, {
type: "POST",
contentType: 'application/json',
data: JSON.stringify(project)
});
};
To decode this on the server side, you will need a JSON decoder of some kind. I'm sure C# has some available.

Categories