JQuery AJAX PUT, not working - javascript

I'm sending a JQuery AJAX call as follows, to update a record in an ActiveRecord DB:
var url_out = '/users/' + args.item.id;
$.ajax({
url: url_out,
type: 'POST',
method: 'PUT',
data: args.item,
success: function(dat) {
alert("did it");
}
In Users controller, I have this:
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
So I need to pass the data that's in args.item, instead, as params[:user]. Can one pass named parameters using the AJAX call?

I might be wrong, but I know that Rails actually is simulating the http verbs by adding a hidden parameter _method with value "PUT" and the actual request is a POST (due to some browsers not supporting all the verbs")
SO, you can try to do a post and add a parameter _method: "PUT"

I'd like to thank #Dom and #Eduard for the help. It turns out I needed to do something like this:
x_out = {};
x_out["first_name"] = args.item.first_name;
x_send = {};
x_send["user"] = x_out;
and that lets me pass the named parameter to the update method in the controller.

Related

How to pass array from js to controller

I have an array in my javascript file app/assets/javascript/pages/books_page.js :
var booksPage = Backbone.Model.extend({
defaults: {
authors: []
}
...
How can I pass that to my controller as a param. The path of my controller is app/controllers/books_controller.rb ?
I think I might need an ajax request and tried the following but it is not working:
$.ajax({
type: "post",
url: "/books_controller",
data: { list_authors: this.get('authors') },
});
Specifically, I am not sure what the url needs to be. Your help here will be greatly appreciated. Thanks.
Backbone (and jQuery) should do all the heavy lifting for you. Set the urlRoot in the model:
var booksPage = Backbone.Model.extend({
urlRoot: '/books',
...
});
and then call save on the instance to send the data to the server:
// Get or create `books` as a `booksPage` instance as usual...
// Then make some changes to `books` using `books.set(...)`...
books.save();
You can use JSON.stringify, and parse it from Controller JSON.parse(params).
$.ajax({
type: "post",
url: "/books_controller",
data: { list_authors: JSON.stringify(this.get('authors')) }
});
type: 'POST',
url: `/books/${this.id}`, // or '/books/' + this.id,
data: {
_method: 'put'
}
This will route you to the BooksController#update. You also need to merge the _method entry into your data object.
"NOTE: Because submitting forms with HTTP methods other than GET and POST isn't widely supported across browsers, all other HTTP methods are actually sent over POST with the intended method indicated in the _method parameter. Rails automatically detects and compensates for this." - Working with JavaScript in Rails

Trying to understand JQuery/Ajax Get/POST calls

Correct me if I'm wrong but it was my understanding that a POST was to be used if I was changing data, and a GET was to be used if I want to retrieve data.
Based on that assumption.
I have (MVC5) app.
My JavaScript
function MyLoadData(myValue) {
$.ajax({
method: 'POST',
url: '/Home/GetMyData',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify({ "MyValue": myValue}),
success: function (data) {
// Do Stuff
}
});
and my controller.
public JsonResult GetMyData(string myValue)
{ // Do Stuff }
This only works if I set the method: 'POST', if I set it to 'GET' it will still make the server call but not pass the myValue to the controller.
Also of note there is no data annotation on the GetMyData method.
In this scenario shouldn't I be using GET to get my data from the controller?
UPDATED based on comments:
function MyLoadData(myValue) {
$.ajax({
method: 'POST',
url: '/Home/GetMyData',
dataType: 'json',
data: { "MyValue": myValue},
success: function (data) {
// Do Stuff
}
});
Both POST and GET methods can pass the myValue to the controller.
GET - Requests data from a specified resource
POST - Submits data to be processed to a specified resource
GET is basically used for just getting (retrieving) some data from the server. Note: The GET method may return cached data.
POST can also be used to get some data from the server. However, the POST method NEVER caches data, and is often used to send data along with the request.
The primary difference between a GET and a POST is that the POST will also submit the form data. In your example, you can use a GET by appending ?MyValue=<myValue> to your URL and WebAPI will assign the value to the Action's parameter.
If the GET request needs to work then use this code block:
function MyLoadData(myValue) {
$.ajax({
method: 'GET',
url: '/Home/GetMyData?myValue=test',
success: function (data) {
// Do Stuff
}
});
Basically, you can use GET or POST to get the data. but in GET, the data is passed through query string. In POST it can be passed both through query string as well as body.
One real world scenario when to use POST-Suppose your method expects Customer parameter and you need to send Customer object as parameter, then you can send the json representation of Customer object through body.but its not possible through GET.
One more reason is security,if you use GET, your method can be called through browser.but if you use POST, the method can't be directly called.
These were the important difference.For more differences see this link - http://www.diffen.com/difference/GET_(HTTP)_vs_POST_(HTTP)

Angular & ASP.NET MVC - Parameter is null when I pass a parameter to my backend Controller

If you look at the parameter of my ASP.NET MVC Controller clientId, it's always null.
the only way i can get it to not be null and actually pass the data through successfully is to create a class... but that gets tedious and I can't create a class for every backend function i make just to get this to work.
Is there a way to pass data successfully without creating a class?
Thank you for any help
Angular Factory
PlaylistsFactory.getUsersForClient = function (clientId) {
return $http({
method: 'POST',
url: '/Show/GetUsersForClient',
data: JSON.stringify(clientId)
});
};
Angular Controller
PlaylistsFactory.getUsersForClient(clientId)
.success(function (userList) {
console.log('success!');
});
ASP.NET MVC Controller
public JsonResult GetUsersForClient(string clientId) //clientId is always null unless i create an object
{
...
}
Try making your JSON parameter match the name of your C# parameter as well as encasing that in the data payload as JSON:
return $http({
method: 'POST',
url: '/Show/GetUsersForClient',
data: {clientId: JSON.stringify(clientId)}
});
};
i would recommend that you follow the rules of a RESTful API.
This means you should use the HTTP verbs like GET (getting data), POST (updating data), PUT (creating data), DELETE (deleting data). See http://www.tutorialsteacher.com/mvc/actionverbs-in-mvc
Then you could also add the parameter you want to pass into the route of your API: /Show/GetUsersForClient/{clientId}. See http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx
In this case you disengage the problem of sending data in the body without having a ViewModel on the MVC-Controller side.
When you want to proceed with your solution, then try creating the Object before sending it:
PlaylistsFactory.getUsersForClient = function (clientId) {
var payload = { clientId: clientId }
return $http({
method: 'POST',
url: '/Show/GetUsersForClient',
data: payload
});
};
MVC / WebAPI also sometime choke when the content-type in the request header is text/plain or application/json. For example: a json-object will not be recognized properly by .Net when sent in text/plain.

angular http post adds extra params to the request

I have the following in a directive:
scope.progressCourse = ->
req_data =
course_id: scope.course.id
success: true
$http.post(
"<%= Rails.application.routes.url_helpers.progress_course_path %>",
req_data
).then (succesful_resp) ->
scope.course = succesful_resp.data.data
scope.init_from_course_object()
, (error_resp) ->
show_error(error_resp)
And, server side, I'd expect to receive the course_id and success params. However, I receive something extra:
Parameters: {"course_id"=>1, "success"=>true, "training"=>{"course_id"=>1, "success"=>true}}
The request is addressed to a controller called TrainingController. I'm running Rails 3.2.13, with angular 1.2.10. Could someone explain why the extra hash appears {"training"=>{"course_id"=>1, "success"=>true}}
UPDATE:
If I add this:
$httpProvider.defaults.transformRequest = (data) ->
if data?
return $.param(data)
return data
and I change the post to:
$http(
method: "POST"
url: "<%= Rails.application.routes.url_helpers.progress_course_path %>",
data: req_data,
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
).then (succesful_resp) ->
Then I only get the 2 params I need. Can someone explain why this behaviour?
Rails has a lot of inbuilt functionality to make dealing with external APIs easier. In this case it has a params_wrapper that will manipulate parameters passed in in a request, nesting them in the hash that it assumes you want.
For example, if you are submitting {name: 'foo', age: 12} to a UsersController, it will assume that they should be wrapped in a nested user key and will do this for you transparently.
Documentation for this wrapper is here:
http://api.rubyonrails.org/v3.2.13/classes/ActionController/ParamsWrapper.html
And the code is here:
https://github.com/rails/rails/blob/v3.2.13/actionpack/lib/action_controller/metal/params_wrapper.rb
If you don't want this functionality, you can disable it by commenting out the wrap_parameters format: [:json] line in /config/initializers/wrap_parameters.rb.

Implementing Ajax calls for a REST API

I have built a back end REST API using Slim Framework and followed the REST format as close as I could.
Once I started working on the Front End I realized that AJAX works great with parameters and not paths
(param file?param=value , paths file/object/method/id)
I am planning on out sourcing or building an APP with xamarin or other 3rd party to consume the API, but for now a Alpha test will be done with HTML and AJAX calls.
Example call example.com/user/test or example.com/advertiser/2
So how do I query the API, do I just concat URL strings?
.ajax({ ... url : 'example.com/user/'+user ...});
EDIT:
Yes I know AJAX is domain sensitive, and Yes I am using verbs GET,POST,PUT and DELETE.
What is going on is the following :
When passing variables in an AJAX request they get appended as
PARAMS example.com/users/?user=Pogrindis
in an REST API at least as far as I read it goes
example.com/users/Pogrindis that's a path
reference parse.com/docs/rest#general-quick
Ajax has set definitions how to do this : https://api.jquery.com/jQuery.ajax/
Your passing user as a param, over get // post method and you are specifying what you expect back.
If i understood the question correctly you are looking at something like:
$.ajax({ url: 'example.com/user/',
data: {user: user}, // Params being sent
type: 'post',// Or get
dataType: 'json' // Or whatever you have
success: function(output) {
//.. do what you like
}
});
There should be no problem.
The data being passed into it will append to the url for GET-requests, i think thats what you mean.. Your data object can be constructed before sending via ajax.
There needs to be a route to query for data. Unless you define some flag on the server to point to the correct location, then you could pass through a route param but you need to have a pointer URL. Building the route can be painful, and subsequent calls will be more challenging but you can do it ?
After doing some research here is a solution used
FRONT END
$.ajax({
url: '/user/'+getid,
data: getdatastring,
type: 'GET',
datatype: 'json',
cache: false,
success: function(data) {
data = JSON.parse(data);
}
});
BACK END
SLIM PHP FRAMEWORK
$app->put('/user/:id', function($id) use ($app,$_pdo) {
$obj = new dbModel($_pdo);
$objApi = new Controller($obj);
$arrParams = json_decode($app->request()->getBody(),true);
$arrUser= $objApi->getUserInfo($id,$arrParams);
print json_encode($arrUser);
});

Categories

Resources