Laravel Ajax Post returns 500 - javascript

I built an ajax post which sends each slider value (I am using jquery ui slider) to my controller.
The Ajax code:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'post',
contentType: "application/json",
url: "{{ Route('editProductPost', $product->id) }}",
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
data: JSON.stringify({
value: getSliderVal,
productId : getPrId
}),
datatype: 'json',
success: function(response) {
// get response
console.log(response.sliderValue)
}
});
And in my Controller I am doing this:
public function editProductPost(Request $request)
{
Log::info($request->get('value'));
return view('product.edit', [
'sliderValue' => $request->get('value')
]);
}
This returns me the correct slider value,
Log::info($request->get('value'));
But I get this error message in my browser console:
POST http://localhost/myApp/public/product/edit/98 500 (Internal
Server Error)
Later on I want to call this sliderValue inside of a php loop in my view.
Edit
I do have a csrf token:
<meta name="csrf-token" content="{{ csrf_token() }}">
Edit
I have done this:
$sliderValue = $request->get('value');
$route = 'updateProduct';
return view('product.edit', compact(['sliderValue', 'route']))->render();
The console print me undefined and if I do this {{ sliderValue }} I get an error that sliderValue is not defined

Little change of your code:
public function editProductPost(Request $request)
{
Log::info($request->get('value'));
$sliderValue = $request->get('value';
return view('product.edit', compact('sliderValue'))->render();
}

The problem here is that you're returning a view in your controller. If your view used {{ $sliderValue }} inside it, it should work. But there's no way for javascript to get the sliderValue variable.
If you wanted the sliderValue as is, you can return this array
return [
'view' => view('product.edit', compact(['sliderValue', 'route']))->render(),
'sliderValue' => $sliderValue
];
That way you're sending to javascript an object with 2 properties, one should contain the view and the second one will only contain the value.

Related

Using HTTP in NativeScript to send Post-data to a TYPO3-Webservice

I'm trying to send form data from a NativeScript app to a TYPO3-Webservice.
This is the JavaScript I'm using:
httpModule.request({
url: "https://my.domain.tld/webservice?action=login",
method: "POST",
headers: { "Content-Type": "application/json" },
content: JSON.stringify({
username:username,
password:password
})
}).then((response) => {
console.log("got response");
console.log(response.content);
//result = response.content.toJSON();
callback(response.content.toJSON());
}, (e) => {
console.log("error");
console.log(e);
});
But I can't read this data in the controller. Even with this:
$rest_json = file_get_contents("php://input");
$postvars = json_decode($rest_json, true);
$postvars is empty. $_POST is empty, too (which is - according to some docs - because the data is sent as JSON and thus the $_POST-Array isn't populated.
Whatever I do, whatever I try, I can't get those variables into my controller.
I tried it with fetch as well as with formData instead of JSON.stringify, same result.
I might have to add, that when I add the PHP-part in the index.php of TYPO3, $postvars is being populated. So I guess something goes missing, until the controller is called.
Any ideas?
the nativescript part seems ok, your problem must be corrected in the server side.
i use similare call and its works
// send POST request
httpModule.request({
method: "POST",
url: appSettings.getString("SERVER") + '/product/list',
content: JSON.stringify(data),
headers: {"Content-Type": "application/json"},
timeout: 5000,
}).then(response => { // handle replay
const responseAsJson = response.content.toJSON();
console.log('dispatchAsync\n\tresponse:', responseAsJson);
}, reason => {
console.error(`[ERROR] httpModule, msg: ${reason.message}`);
});

Ajax not posting in laravel controller

<script type="text/javascript">
$(document).ready(function(){
$('#mainmenu').change(function(){
var main_menu_id = $('#mainmenu').val();
$.ajax({
type: 'POST',
url: '/sub',
data: {"main_menu_id": main_menu_id,_token: '{{csrf_token()}}'
success: function (data) {
var submenus = data.submenus;
for(var i=0; i<submenus.length; i++){
$('#submenu').append('<option>'+submenus[i]+'</option>');
}
},
error: function () {
alert('what ever');
}
});
});
</script>
My route
Route::post('/sub','TicketController#sub');
And my controller
public function sub(Request $request)
{
dd($request->all());
return Response([
'submenus' => DB::connection("mysql2")->table('applicationsubmenu')
->join('applicationmenu', 'applicationmenu.Id', '=',
'applicationsubmenu.ApplicationMenuId')
->select('applicationsubmenu.*')
->where('applicationmenu.MainMenuId', '=', $request->main_menu_id)
->get()->toarray(),
]);
}
I am trying to populate an option submenu from depending from user option menu selection.To do that I tried building an ajax but it seems not to work at all.Neither the laravel function seems to be called at all!
Try to setup the ajax requests on the project properly:
In header
<meta name="csrf-token" content="{{ csrf_token() }}" />
In script
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
</script>
Did you use ajax middleware
Route::post('/sub','TicketController#sub')->middleware('ajax');;
Why are you dumping the $request in your controller?
dd($request->all());
Laravel docs:
The dd function dumps the given variables and ends execution of the script https://laravel.com/docs/5.6/helpers#method-dd
Also when getting values from $request... you are doing this:
->where('applicationmenu.MainMenuId', '=', $request->main_menu_id)
but you should get the values like this:
->where('applicationmenu.MainMenuId', '=', $request->input('main_menu_id')
or if you want an array of request then you should set first:
$input = $request->all();
and then call the value like this:
$input->main_menu_id
you forget to send the token
$.ajax({
type: 'POST',
url: '/sub',
data: {'_token':'{{csrf_token()}}',"main_menu_id": main_menu_id},
success: function (data) {
alert(data);
},
error: function () {
alert('what ever');
}
});

How to pass data from ajax to laravel 5.2 controller via post method

Hello StackOverflow family. This is my very first question and I hope to get help.
I'm new to laravel framework and am using version 5.2 in my project.
Am trying to pass data using the post method from my ajax function to a particular controller method but no data is passed to the controller.
I followed the steps in this forum https://laracasts.com/discuss/channels/laravel/process-data-in-controller-using-ajax-in-laravel but can't get it to work. Here is what I've done so far.
My JavaScript (post_script.js):
$.ajax({
method: 'POST',
url: './home',
data: {
userID: 76,
userName: 'Jimmy'
},
});
Note that this file is saved in assets/js directory in the laravel structure. Here is what I have in my route file (routes.php):
Route::get('/', "MyController#home");
Route::get('home', "MyController#home");
Here is the function I have in MyController.php file:
function home(Request $request) {
$userID = $request['userID'];
$userName = $request['userName'];
return view('home', [
'userID'=> $userID,
'userName' => $userName
]);
}
In my view, I tried to access it like this:
<p>User ID: {{$userID}}</p>
<p>User Name: {{$username}}</p>
Nothing is displayed! Please what am I doing wrong? I need your help. Forgive me if my question is not proper but I hope you get what I mean. Thank you
Your AJAX is POSTing, but you have no POST route set, only GET. Add a POST route, like so:
Route::post('home', "MyController#home");
First check with your developer/network tool (eg. firebug) wether your ajax call reaches the desired controller/functions and that the parameters are forwarded correctly.
A safe way to specify Url in the ajax call in the Laravel environment is using the URL facade like this:
url: "{{ URL::to('home'); }}",
In order to do it like this however you must store your js as a myscript.blade.php (!!) file and #include it into your view accordingly.
For receiving your posted parameters in the controller function there is no need to declare function arguments, you can simply use the Input::Get() function eg. like this:
public function home()
{
$userID = Input::Get('userID');
$userName = Input::Get('userName');
return view('home', [ 'userID'=> $userID, 'userName' => $userName ]);
}
If you try to do POST request you may need to have X-CSRF-Token.
Add this to meta:
<meta name="csrf-token" content="{{ csrf_token() }}">
And setup your AJAX:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
In Laravel docs: https://laravel.com/docs/5.2/routing#csrf-x-csrf-token
First you need set up dataType for ajax request like this (if you using jQuery)
$.ajax({
method: 'POST',
url: './home',
dataType: 'json'
data: {
userID: 76,
userName: 'Jimmy'
},
})
then try use into your controller as follow
Request::json()
and see result
Also you may use Input::get() :
Request::get('userID')
you can use route name to pass your data to the controller
$.ajaxSetup({
headers:{'X-CSRF-TOKEN': $("meta[name='csrf-token']").attr('content')}
});
$.ajax({
type:'POST',
url: '{{route("route_name_with_post_method")}}',
data:{
'id': data
},
success:function(r){
},error:function(r) {
}
});

pass javascript response variable to spring controller function

The following javascript code works with the facebook login window appearing and allowing a user to login. The response values are captured and I know it works as alerts appear where setup but I cannot pass the value back to a controller method.
#RequestMapping(value ="/getAccessToken" , method = RequestMethod.POST)
public #ResponseBody String getAccessToken(#RequestBody String token){
System.out.println(token);
return token;
}
Javascript method called:
function doLogin() {
FB.login(function(response) {
alert(response);
console.log(response);
if (response.authResponse) {
alert(response.authResponse.userID);
alert(response.authResponse.accessToken);
var Token = response.authResponse.accessToken;
alert(Token);
$.ajax({
type: "POST",
url: "/HelloController/getAccessToken",
data: Token,
success: function (result) {
alert("Token");
},
error: function (result) {
alert("oops");
}
});
document.getElementById('loginBtn').style.
display = 'none';
getUserData();
}}, {perms:'manage_pages',
scope: 'email,public_profile', return_scopes: true});
};
The error I get is the following:
WARN 25660 --- [nio-8080-exec-9]
o.s.web.servlet.PageNotFound :
Request method 'POST' not supported
Appreciate responses.
The problem could be that you are using a new version of JQuery that sends request data as post form data instead of JSON as default. Try changing your ajax call to the following. The form data would not be recognized by your controller so if this is the case you should see a 404.
$.ajax({
type: "POST",
traditional: true,
url: "/HelloController/getAccessToken",
data: JSON.stringify(Token),
success: function (result) {
alert("Token");
},
error: function (result) {
alert("oops");
}
});
For reference see this post: Send JSON data via POST (ajax) and receive json response from Controller (MVC)

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'
})
})

Categories