laravel cannot post data with ajax server status 419 - javascript

I am doing a project with Laravel.
When I change the selected option of the following select element I should insert the selected value to mysql database to retrieve all the data about the selected id from the server (for example the name of the user).
This is the select element (adminArea.blade.php):
<select name="employees" onchange="fillEmployeeData(this)" class="form-control col-sm-6" id="employees">
<option value="0"></option>
#foreach ($users as $user)
<option value="{{ $user->id }}">{{ $user->surname . ' ' . $user->name }}</option>
#endforeach
</select>
And this is the called function (adminArea.blade.php)::
function fillEmployeeData(emp_id) {
var emp_selected = emp_id.value;
$.ajax({
type: "POST",
url: "{{ route('adminAreaPostEmployee') }}",
data: 'emp_selected=' + emp_selected,
success: function (data) {
var emp_data = JSON.parse(data);
alert(emp_data);
}
});
};
These are my routes (web.php):
Route::get('/adminarea', 'AdminAreaController#index')->name('adminArea');
Route::post('/adminarea/postemployee', 'AdminAreaController#post_employee')->name('adminAreaPostEmployee');
And these are my controller methods (adminAreaController.php):
public function post_employee(Request $request)
{
$select = $request->get('emp_selected');
$user = User::where('id', $select);
echo $user;
}
public function index()
{
$operations = Operation::all();
$users = User::all()->sortBy('surname');
$rooms = Room::all();
return view('adminArea', compact('users', 'rooms', 'operations'));
}
However, when I change the selected value nothing happens... and if I go to the developer tools I see the following error:
Failed to load resource: the server responded with a status of 419
(unknown status).
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The GET method is not supported for this route. Supported methods:
POST.
I don't see any alert. Someone can help me?

The HTTP status code for the MethodNotAllowedHttpException is 405
See here
public function __construct(array $allow, string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
$headers['Allow'] = strtoupper(implode(', ', $allow));
parent::__construct(405, $message, $previous, $headers, $code);
}
A TokenMismatchException HTTP status code is 419
See here
protected function prepareException(Exception $e)
{
if ($e instanceof ModelNotFoundException) {
$e = new NotFoundHttpException($e->getMessage(), $e);
} elseif ($e instanceof AuthorizationException) {
$e = new AccessDeniedHttpException($e->getMessage(), $e);
} elseif ($e instanceof TokenMismatchException) {
// HTTP Status code is send in the header here
$e = new HttpException(419, $e->getMessage(), $e);
} elseif ($e instanceof SuspiciousOperationException) {
$e = new NotFoundHttpException('Bad hostname provided.', $e);
}
return $e;
}
So this appears to be a CSRF token issue
Make sure that you have a meta tag on the head of your document like this
<meta name="csrf-token" content="{{ csrf_token() }}">
Also from the JQuery Ajax Documentation
I think that the HTTP method should be defined as method parameter not type (though type works ¯\_(ツ)_/¯)
// Send a CSRF token header with every Ajax request
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
function fillEmployeeData(emp_id) {
var emp_selected = emp_id.value;
$.ajax({
method: "POST",
url: "{{ route('adminAreaPostEmployee') }}",
data: 'emp_selected=' + emp_selected,
success: function (data) {
var emp_data = JSON.parse(data);
alert(emp_data);
}
});
};
But now you're gonna get an error
Object of class Illuminate\Database\Eloquent\Builder could not be converted to string
Because you're trying to return a query builder instance User::where('id', $select) instead of the user record itself serialized
I think you may want to do this
public function post_employee(Request $request)
{
$select = $request->get('emp_selected');
return User::find($select);
}
Hope this helps

Try to 'method' instead of 'type' . You should use type if you're using versions of jQuery prior to 1.9.0
function fillEmployeeData(emp_id) {
var emp_selected = emp_id.value;
$.ajax({
method: "POST",
url: "{{ route('adminAreaPostEmployee') }}",
data: 'emp_selected=' + emp_selected,
success: function (data) {
var emp_data = JSON.parse(data);
alert(emp_data);
}
});
};

this is a CSRF protection of laravel,
you can add csrf meta tag in the head
<meta name="csrf-token" content="{{ csrf_token() }}">
and in the top of the script write
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});

Related

Laravel 6 Error - Undefined property: App\Http\Controllers\GetContentController::$request

I am trying to send form data including files (if any) without form tag via Ajax request. However, I am getting the following error message
Undefined property: App\Http\Controllers\GetContentController::$request
Here are my codes
Controller
public function GetContentController($params){
$CandidateFullName = $this->request->CandidateFullName;
$CandidateLocation=$this->request->CandidateLocation;
//inserted into database after validation and a json object is sent back
Web.php
Route::match(['get', 'post'], '{controller}/{action?}/{params1?}/{params2?}', function ($controller, $action = 'index', $params1 = '',$params2 = '') {
$params = explode('/', $params1);
$params[1] = $params2;
$app = app();
$controller = $app->make("\App\Http\Controllers\\" . ucwords($controller) . 'Controller');
return $controller->callAction($action, $params);
})->middleware('supadminauth');
Blade
<input type="text" id="CandidateFullName" name="CandidateFullName" class="form-control">
<input type="text" id="CandidateLocation" name="CandidateLocation" class="form-control">
<button id="final_submit">Submit</button>
<script>
$('#final_submit').click(function(e){
e.preventDefault();
var data = {};
data['CandidateFullName']= $('#CandidateFullName').val();
data['CandidateLocation']=$('#CandidateLocation').val();
submitSaveAndNext(data)
});
function submitSaveAndNext(data){
//console.log(data);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': '{{csrf_token()}}'
}
});
$.ajax({
type : "POST",
url : '{{url("GetContent/submitContent")}}', //GetContentController ,but without Controller in the end
dataType : "json",
contentType : "application/json",
data : JSON.stringify(data),
success : function(response){
//console.log("response ",response);
if(response.message=="success"){
swal({
title:"Success",
type: "success",
});
}else{
swal({
title:"Sorry! Unable to save data",
type:"warning"
})
}
},
error:function(xhr, status, error){
swal({
title:"Sorry! Unable to save data",
type:"warning"
})
}
}) //ajax ends
I don't think controller instance in laravel possess the property having request instance, you'll have to type-hint to obtain the object of the request
public function GetContentController($params) {
// $this->request is the issue
$CandidateFullName = $this->request-> CandidateFullName;
$CandidateLocation = $this->request->CandidateLocation;
}
So you can try either of the below-given solutions
// make sure include the Request class into your controller namespace
public function GetContentController($params, Request $request) {
$CandidateFullName = $request->input('CandidateFullName');
$CandidateLocation = $request->input('CandidateLocation');
}
Or use the helper function for request
public function GetContentController($params) {
$CandidateFullName = request('CandidateFullName');
$CandidateLocation = request('CandidateLocation');
}
These links will help you get more details :
https://laravel.com/docs/8.x/requests#accessing-the-request
https://laravel.com/docs/5.2/helpers#method-request

Select2 POST AJAX Request 500 Error Laravel

I'm trying to use select2 retrieving large data in my dropdown using the following article.
Getting 500 Internal Server Error in my console log.
I have store token in HTML meta tag.
<meta name="csrf-token" content="{{ csrf_token() }}">
And sending a token as a parameter in my POST request.
var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
$(document).ready(function(){
$( "#test" ).select2({
ajax: {
url: "path/to/url",
type: "POST",
dataType: 'JSON',
delay: 250,
data: function (params) {
return {
_token: CSRF_TOKEN,
search: params.term // search term
};
},
processResults: function (response) {
return {
results: response
};
},
cache: true
}
});
});
<select class="test" id="test" style="width:100%;"></select>
I have checked routes using php artisan route:list and clear cache using php artisan config:cache. But still getting the same error link. and link.
Is there anything I'm missing? I would be grateful if you can help me out to debug/inspect my Request and Response.
Tried
error: function(err){
console.log(err)
}
Server-Side \ Controller
public function getdata(Request $request){
$search = $request->search;
if($search == ''){
$data = DB::table('table')
->orderby('name','asc')
->select('id','name')
->limit(5)->get();
}else{
$data = DB::table('table')
->orderby('name','asc')
->select('id','name')
->where('name', 'like', '%' .$search . '%')
->limit(5)->get();
}
$response = array();
foreach($data as $i){
$response[] = array(
"id"=>$i->id,
"text"=>$i->name
);
}
return response()->json($response);
}
Happy Coding.

How to delete a file on the server? FilePond.revert does not pass parameters to the laravel controller

FilePond.revert does not transfer unique id files to the laravel controller.
How to delete the downloaded file by ID?
FilePond JS
var csrf = $('meta[name="csrf-token"]').attr('content');
FilePond.setOptions({
server: {
url: '/file/upload/',
process: {
url: 'process',
headers: {
'X-CSRF-TOKEN': csrf
},
onload: function (responce) {
console.log(JSON.parse(responce))
},
},
revert: {
url: 'revert',
headers: {
'X-CSRF-TOKEN': csrf
},
onload: function (x) {
// X - empty, why????
console.log(x)
},
},
load: {
url: 'load/',
},
},
})
FilePond.create(document.querySelector('.filepond[type="file"]'), {
files: [
{
source: '11',
options: {
type: 'local',
}
},
]
});
Loading pictures work successfully.
Return unique ID file in response.
public function process(){
$file = FilesUploadService::save();
return response($file->collection->id, 200)
->header('Content-Type', 'text/plain');
}
Empty here I can't find the file id. Which need to be removed
public function revert(Request $request){
return response()->json($request->all());
}
Anyone still struggling:
request->getContent() will return the request payload sent by filepond.
In revert method in controller:
public function revert(Request $request){
$fileId = request()->getContent();
//use $fileId to delete file from filesystem
}
The onload method below should return a unique id to FilePond. So, for example, if the unique id is found in responce.id you add the return line like shown.
onload: function (responce) {
console.log(JSON.parse(responce))
return JSON.parse(responce).id // added
},
Did you get this to work? FilePond uses the DELETE header when reverting, that may be why you're not getting anything from request.
Maybe something like this?
public function revert(){
$response = new stdClass();
if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
$file_name = strip_tags(file_get_contents("php://input"));
if (is_string($file_name) && FilesUploadService::delete($file_name)) {
$response->id = $file_name;
$response->success = true;
} else {
$response = false;
}
} else {
$response = false;
}
return response()->json($response);
}
I've been struggling with reverting/deleting an early uploaded file using FilePondfor a few hours but after scavenging on there documentation I have figured out a quick hack to get around the situation.
On your JavaScript side you'd be doing something like the following to upload the file via XHRobject:
<script>
const pondElement = document.querySelector('input[type="file"]');
const pond = FilePond.create( pondElement );
FilePond.setOptions({
server: {
url: "{!! route('ajax.uploadFiles') !!}",
process: {
headers: {
'X-CSRF-TOKEN': '{!! csrf_token() !!}'
}
},
}
});
</script>
Now to the tricky part: Reverting/Remove:
<script>
const filepond_root = document.querySelector('.filepond--root');
filepond_root.addEventListener('FilePond:processfilerevert', e => {
$.ajax({
url: "{!! route('ajax.revertFiles') !!}",
type: 'POST',
data: {'_token': '{!! csrf_token() !!}', 'filename': e.detail.file.filename}
})
});
</script>
On your ServerSide (Laravel) it's as easy and straight forward as the following:
public function uploadFiles(Request $request)
{
if ($request->has('attachments')) {
if (!file_exists(storage_path('app/tmp'))) {
mkdir(storage_path('app/tmp', 0777, true));
}
$file = $request->file('attachments')[0];
$file_name = $file->getClientOriginalName();
$file_path = storage_path("app/tmp/{$file_name}");
$file->storeAs(null, $file_name, 'tmp');
}
}
public function revertFiles(Request $request)
{
unlink(storage_path("app/tmp/{$request->filename}"));
}
PS: This code is just for demo purposes, please secure your forms and provide a better user experience.
Filepond script at Laravel blade file
<!-- filepond script -->
<script>
const inputElement = document.querySelector('input[id="file"]');
const pond = FilePond.create( inputElement );
FilePond.setOptions({
server: {
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
process: {
url: '{{ route('store') }}',
},
revert: {
url: '{{ route('destroy') }}',
}
}
});
</script>
Destroy method at Laravel Controller file
public function destroy(Request $request)
{
$folder = json_decode($request->getContent()); // folder name
}
i have faced the exact same problem. i did 2 thing to fix it.
must have the process.onload function and return the object Id/path. this Id/path will automatically pass to revert function.
in the controller method which handle the revert call. the Id/path from step 1, can be obtain from calling $request->getContent(), notice that $request->all() can not grab the value.

Get variable from javascript into controller

I need to have a variable from an java script function into my controller.
Here you can see my ajax function
<script>
$('#spielAuswahl').on('change', function(e){
console.log(e);
var spielID = e.target.value;
//ajax
$.get('/spieler?spielID=' + spielID, function(data){
console.log(data);
});
});
</script>
And this is my web router
Route::get('/spieler', 'SpielerController#getSpieler');
And here my controller function
public function getSpieler(){
$spielID = Input::get(spielID);
echo $spielID;
}
I have this issue
jquery.js:9664 GET http://localhost:8000/spieler?spielID=3 500
(Internal Server Error)
What I have to change?
I don't know what you exatly want to do, but here is a solution to pass a value.
You can name your routes, example:
Route::post('/spieler', ['as' => 'spieler', 'uses' => 'SpielerController#getSpieler']);
Your jquery:
var token = "{{ Session::token() }}";
$('#spielAuswahl').on('change', function(e){
console.log(e);
var spielID = e.target.value;
$.ajax({
method: "POST",
url: "{{ route('spieler') }}",
data: {id: spielID, _token: token}
});
}
Finally your controller:
public function getSpieler(Request $request) {
$id = $request['id'];
echo $id;
}
The code you have shown is missing some quotes:
public function getSpieler(){
$spielID = Input::get('spielID'); // quote `spielID` here
echo $spielID;
}
If you're using Laravel 5, you can use the request:
use Illuminate\Http\Request;
...
public function getSpieler(Request $request) {
echo $request->spielID;
}
You can find out more more details about your 500 Server Error in the web server logs, and storage/logs/laravel.log.

How to pass hidden field value via ajax to codeigniter controller

I have a view file which contains a button (link):
<a href id="savebutton" class="btn btn-warning">Save</a>
Somewhere else in this view I have also declared some hidden fields in a form that contain my userid and vacancyid.
echo form_input(dataHiddenArray('userid', $this->auth_user_id));
echo form_input(dataHiddenArray('vacancyid', $vacancydetails[0]->vacancy_id));
These hidden fields translate to:
<input type="hidden" value="2" class="userid">
<input type="hidden" value="1" class="vacancyid">
Now I want to be able to send these values to my controller (via AJAX) so that I can insert them in my database.
My JS file looks like this:
$(function() {
var postData = {
"userid" : $("input.userid").val(),
"vacancyid" : $("input.vacancyid").val()
};
btnSave = $('#savebutton'),
ajaxOptions = {
cache: false,
type: 'POST',
url: "<?php echo base_url();?>dashboard/vacancy/saveVacancy",
contentType: 'application/json',
dataType: 'text'
};
btnSave.click(function (ev) {
var options = $.extend({}, ajaxOptions, {
//data : $(this).closest('form').serialize()
data: postData
});
ev.preventDefault();
// ajax done & fail
$.ajax(options).done(function(data) {
alert(data); // plausible [Object object]
//alert(data[0]); // plausible data
console.log(data); // debug as an object
}).fail(function (xhr, status, error) {
console.warn(xhr);
console.warn(status);
console.warn(error);
});
});
And my controller looks like this (it is not doing much because it doesn't return anything):
public function saveVacancy() {
//$this->load->model('user/usersavedvacancies_model');
/*$data = array(
'userid' => $this->input->post('userid'),
'vacancyid'=>$this->input->post('vacancyid')
);*/
echo $this->input->post('userid');
}
Minor changes to javascript
$(function () {
var postData = {
"userid": $("input.userid").val(),
"vacancyid": $("input.vacancyid").val()
};
btnSave = $('#savebutton'),
ajaxOptions = {
type: 'POST',
url: "<?php echo base_url('dashboard/vacancy/saveVacancy);?>",
dataType: 'json'
};
btnSave.click(function (ev) {
var options = $.extend({}, ajaxOptions, {
//data : $(this).closest('form').serialize()
data: postData
});
ev.preventDefault();
// ajax done & fail
$.ajax(options).done(function (data) {
console.log(data); // debug as an object
if (data.result === 'success') {
alert("Yeah, it saved userid " + data.userid + " to vacancy id " + data.vacancyid);
}
}).fail(function (xhr, status, error) {
console.warn(xhr);
console.warn(status);
console.warn(error);
});
});
});
In the controller
public function saveVacancy()
{
//assigning a more useable object name to the model during load
$this->load->model('user/usersavedvacancies_model', 'save_vacancy');
$data = array(
'userid' => $this->input->post('userid'),
'vacancyid' => $this->input->post('vacancyid')
);
//send data to model and model returns true or false for success or failure
$saved = $this->save_vacancy->doSaveId($data); //yes, I made up the method, change it
$result = $saved ? "success" : "failed";
echo json_encode(array('result' => $result, 'userid' => $data['userid'], 'vacancyid' => $data['vacancyid']));
}
You need to understand that $.ajax takes two methods i.e GET and POST and from the documentation you can see that default method is GET so Since you have not defined method as GET/POST probably the method is taken GET so first change define ajax method to POST as well as you need to be clear about dataType of ajax it may be one of JSON/html and default is json.
$.ajax({
method: "POST",
url: url,
data: data,
dataType:'html'
});
I guess this helped you can learn detail from
Learn more.

Categories

Resources