Symfony2 + AJAX return source code - javascript

I made an ajax code to send the form data to the controller but it's returning source code instead.
I am using FOSJsRoutingBundle to generate my route in my js code (i installed and used it like the doc said), this is working and return this when it's call on my js
/xampp/folder/web/app_dev.php/chat/
I render my form in twig like this
{{ form_start(form, {'action': '{{ path("chat_page") }}', 'method': 'POST'}) }}
{{ form_widget(form) }}
<input type="submit" value="Send">
{{ form_end(form) }}
My js code look like this
$('form').submit(function(event) {
event.preventDefault();
var url = Routing.generate('chat_page');
console.log(url);
console.log($('#chat_message').val());
$.ajax({
url: url,
type: $('form').attr('method'),
data: $('#chat_message').val(),
success: function(data){
console.log(data);
}
});
$('#chat_message').val('').focus();
});
My controller (probably not used when ajax is done) is this one
/**
* #param Request $request
* #Route("/chat/", name="chat_page", options={"expose"=true})
*
* #return \Symfony\Component\HttpFoundation\Response
*/
public function indexAction(Request $request)
{
$chatForm = $this->createForm(ChatType::class);
$client = $this->get('elephantio_client.socketio_key');
$elephantIOClient = $client->getElephantIO();
$elephantIOClient->initialize();
if ($request->isXmlHttpRequest()) {
$chatForm->handleRequest($request);
$chatData = $chatForm->getData();
dump($chatData);
$elephantIOClient->emit('chat message', ['msg' => $chatData]);
}
$elephantIOClient->close();
return $this->render('chat/index.html.twig', [
'form' => $chatForm->createView(),
]);
}
I think it's a problem with the url (who seems good) who don't call my controller but i don't know what.
I readed some topic about ajax with symfony and it's all the time like i made. If you have any ideas to help me to fix this.
Thanks

It's rendering your HTML code because in your controller you are rendering your HTML code with this :
return $this->render('chat/index.html.twig', [
'form' => $chatForm->createView(),
]);
You need to add a return response inside your if clause to return something else when it's an ajax request :
if ($request->isXmlHttpRequest()) {
$chatForm->handleRequest($request);
$chatData = $chatForm->getData();
dump($chatData);
$elephantIOClient->emit('chat message', ['msg' => $chatData]);
return new Response("ok");
}

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

Ajax ignoring URL

I try to make an ajax request through JQuery triggering an onClick event, but when it sends the AJAX request I receive:
PATCH http://localhost:8000/courses 405 (Method Not Allowed) (Current page) Because it doesn't get the URL with the id
HTML
#foreach ($courses as $course)
<tr>
<td>{{ Form::select('year', $years, ['class' => 'form-control'], [ 'placeholder' => $course->academicYear]) }}</td>
<td>{{ Form::select('subject', $subjects, ['class' => 'form-control'], [ 'placeholder' => $course->subject]) }}</td>
<td>
Save
<input type="hidden" id="idCourse" value="{{ $course->id }}">
(...)
JQUERY + AJAX
$('#saveCourse').click(function(e){
e.preventDefault();
var id = $('#idCourse').val();
// Ignore this logic
var values = {year: "", subject:"", id: id};
var parameters = ['year', 'subject'];
var i = 0;
$('td > select option:selected').each(function() {
values[parameters[i]] = $(this).text();
i++;
});
// Ajax request
$.ajax({
type: 'patch',
// Appending the course id here not working,
// but if i put anything else like /blabla/ + id ajax doesn't ignore it...
url: '/courses/' + id,
headers: {'X-CSRF-Token': csrf_token},
dataType: 'json',
data: values,
success: function (response) {
console.log("SUCCESS: " + response);
},
error: function (reject) {
if( reject.status === 422 ) {
$("#error").text("Los datos dados no cumplen el formato requerido.");
}
}
});
});
WEB.PHP
/* -----COURSE_ROUTES------ */
Route::resource('courses', 'CourseController')->except([
'create', 'edit'
]);
ROUTES
EDIT
If I use POST instead of PATCH in type AJAX gets the id.
Found a GitHub issue with the same problem https://github.com/jquery/jquery/issues/3944
PUT and PATCH are request methods. An HTTP error of 405, which you get means that the server knows the request method, but the service does not support it. Read more here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405
not sure if matters but try PATCH instead of patch
type: 'PATCH',
I forgot to put this condition at the start of the update method in the controller... Now it works!
if(request()->ajax()) { ... }
As mentioned below the 405 (METHOD NOT ALLOWED) basically means you're ajax request method PATCH is not allowed for the specific resource on the server.
If you using a routing library you can go their docs and search how to change this behavior. A route can accept one or multiple request methods, I assume that the Route::resource create a route with method POST by default, which explains that the ajax request works in POST type.

Internal Server Error 500 when creating in laravel using ajax jQuery, wrong variables format from ajax to controller

I'm trying to create a new service option while creating a bill (a bill can have many services), it's like creating a new tag, or category while writing post without reloading, but i have this internal server error 500, i think the problem is in the Controller because it works fine when i comment the create in controller, route and csrf and stuff are checked, thanks for helping me !
In my javascript :
var max_service_id = {{$max_service_id}};
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$("#add_service_button").on("click",function(e){
e.preventDefault();
var service_name = $("input[name=service_name]").val();
var service_category = document.getElementById('service_category').value;
var service_description = $("input[name=service_description]").val();
$.ajax({
type:'POST',
url:'/service/add-in-bill',
dataType: 'json',
data:{
name : service_name,
category_id : service_category,
description : service_description
},
success:function(data){
if (data.message) {
//This is error message
alert(data.message);
}
if (data.success) {
alert(data.success);
var newService = new Option(service_name, max_service_id, false, true);
$('.multipleSelect').append(newService).trigger('change');
max_service_id++;
$("#add_service_div").hide("fast");
}
}
});
})
});
In my controller :
$validator = Validator::make($request->all(), [
'name' => 'required|unique:services',
'category_id' => 'required',
]);
if ($validator->fails()) {
return response()->json(['message'=>$validator->errors()->all()]);
} else {
// It works fine when i comment this, so i think the problem is something about variables from javascript to php stuff
Service::create($request->all());
return response()->json(['success'=>'Create service success !']);
}
//
// I think the problem is in the Controller because it works fine when i comment the "Service::create($request->all());"

Django - .ajax() method is not working properly

I'm writing Ajax code to hit the database to edit model instances. But the code is not working well. The first alert statement does work, but not the other alert statements. Code in success or error does not respond. Everything seems good. I have no idea how this happened though.
book/detail.html:
<script>
$(document).ready(function () {
$("#add").click(function() {
alert('clicked');
$.ajax({
url: '{% url "cart:add_to_cart" %}',
// handle a successful response
success: function (response) {
alert("Testing.");
("#cartButton").text("Cart" + "(" + response.quantity + ")");
},
error: function (response) {
alert('Got an error');
}
});
});
});
</script>
cart.view.py:
def add_books(request):
c = Cart.objects.get(user=request.user)
q = request.GET.get('quantity')
book_id = request.GET.get('bookID')
<some code here>
response = {
'quantity': BooksInCart.objects.filter(cart=c).aggregate(item_quantity=Sum('quantity'))['item_quantity']
}
return JsonResponse(response)
cart.urls:
app_name = 'cart'
urlpatterns = [
path('add_books/', views.add_books, name='add_to_cart')
]
If you are changing data in the database, you should be using a post-type request. Include method: 'POST' and the csrf token in your ajax call and then check for for a post-type request in your view:
if request.method == 'POST':
To set the csrf token put {% csrf_token %} in your template in order to render the token, and then user JQuery to load the token value into the data portion of the ajax call:
data = {'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()}

Laravel 4: manipulating ajax data through controller

I'm new at Laravel and ajax. I'm trying to get the data from a form via ajax and calling a method in the controller via that same ajax. The method in the controller searches the database and then returns a json response that gets handled by ajax(that last part I'm still thinking about, I haven't really done it yet).
Let me show you what I have now:
Routes.php:
Route::get('/', 'HomeController#getIndex');
Route::post('/', 'HomeController#postIndex');
HomeController:
public function getIndex()
{
return View::make('index');
}
public function postIndex()
{
$match = Input::get('search');
$results = Customers::where('name', 'like', '%'.$match.'%')->get();
return Response::json(array('results' => $results));
}
And my index.blade.php View :
<script>
$(document).ready(function() {
$('form#find').submit(function() {
$.ajax({
url : 'CustomerSearch/Public',
type: 'post',
dataType: 'json',
data: $('form#find').serialize(),
});
return false;
});
});
and the form:
{{ Form::open(array('url' => '', 'method' => 'POST', 'id' => 'find')) }}
{{ Form::text('search', '', array('class' => 'search-query', 'placeholder' => 'Search')) }}
{{ Form::submit('Submit', array('class' => 'btn btn-info')) }}
{{ Form::close() }}
So I should be getting the data from the form then sending it to the "postindex" method in the controller so it gets processed and then sent back, right? Except I get the error "Controller method [index] not found." when I don't actually call any index method since they are both named differently.
I'm new at this so sorry if it's not clear.
UPDATE:
Like I said in the commentaries, I found out combining the route into a route::controller got rid of my previous problem but unfortunately I'm still unable to get the ajax to send data to my controller. I get no errors, but the ajax doesn't load anything to the controller. Any idea what might be wrong with my ajax?:
$(document).ready(function() {
$('form#find').submit(function() {
$.ajax({
url : '{{URL::to('/')}}',
type: "POST",
dataType: 'json',
data: { search: $('.search-query').val() },
success: function(info){
console.log(info);
}
});
return false;
});
});
Just use in your controller:
return json_encode(array('key' => 'val'));
For the input of data, I moved to a JQuery plugin that works nicely for me. Follow this link.
This is how a function looks like:
function someName(){
// A plugin is used for this function
$('#form_id').ajaxForm({
url: '/',
type: 'post',
dataType: 'json',
success: function(response){
alert(response.key);
}
});
}
and the corresponding form:
<form id="form_id">
<!-- Put your fields here -->
<input type="submit" onclick="someName()">
</form>
I would suggest you use this method, which may depend on the plugin but is the simplest. Of course, you could use the .submit() statement instead of binding it to the onclick event

Categories

Resources