How to display form errors after ajax query and JsonResponse - json

I have a form to add product using jquery and ajax. Adding proucts work fine but I'd like to know how to display form errors with JsonRespone
This is the jquery code
$(document).on('submit', "#form-add", function (e) {
e.preventDefault();
$.ajax({
type: 'post',
dataType: 'json',
data: $(this).serialize(),
url: Routing.generate('admin_add_product'),
success: function (msg) {
},
error: function(msg){
// do something to display errors
}
});
return false;
});
and this is the action
public function addAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$product = new Product();
$form = $this->createForm(new ProductType(), $product);
if ($request->isXmlHttpRequest()) {
if ($request->getMethod() == 'POST') {
$form->handleRequest($request);
if ($form->isValid()) {
$em->persist($product);
$em->flush();
$this->get('session')->getFlashBag()->add('success', 'Your product has been added to your cart.');
$response = new JsonResponse();
return $response;
} else {
// return errors
}
}
}
}

Related

I am getting error sending status code in laravel apide

When sending response code in laravel api, validation does not enter.
I can view it from the network, but when I send the status code, the console prints an error and I cannot print the validations on the blade page. If I don't send status code I can print validations.
Following my code: StudentController
public function store(Request $request): object
{
$validate = Validator::make($request->all(),[
'name' => 'required',
'course' => 'required',
]);
$data = [
'name' => $request->name,
'course' => $request->course,
];
if ($validate->fails()){
return response()->json(['success' => false, 'errors' => $validate->messages()->all()],422);
}
Student::insert($data);
return response()->json(['success' => true, 'message' => "Registration Successful"]);
}
ajax
$(document).ready(function (){
$('#createBtn').on('click',function (e) {
e.preventDefault();
let form = $('#student-add').serialize();
$.ajax({
'url': "{{ route('students.store') }}",
'data': form,
'type': "POST",
success:function (result) {
$('#ajax-validate ul').text("");
if(result.success === true){
console.log("True");
}else {
result.errors.forEach(function (item) {
$('#ajax-validate ul').append('<li>'+item+'</li>');
});
}
}
});
});
});
console
network
You have your response.errors.forEach inside of your success: function(), but 422 (or any 400) code doesn't get handled by the success function, but rather the error function:
$(document).ready(function () {
$('#createBtn').on('click', function (e) {
e.preventDefault();
let form = $('#student-add').serialize();
$.ajax({
url: "{{ route('students.store') }}",
data: form,
type: 'POST',
success: function (result) {
if (result.success === true) {
// Do whatever on `2XX` HTTP Codes
}
},
error: function (response) {
if (response.status === 422) {
let responseJson = response.responseJSON ? response.responseJSON : { errors: [] };
$('#ajax-validate ul').text('');
responseJson.errors.forEach(function (item) {
$('#ajax-validate ul').append('<li>'+item+'</li>');
});
} else {
console.log('Unhandled Error:', response)
}
}
});
});
});
Now when an 422 error is explicitly triggered, you code can properly handle the validation errors.

Cannot access data of deserialized json

I'm using ajax to send data to my controller, here's how I do it
var formData = JSON.stringify( $('#SubmitForm').serializeArray() );
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'POST',
data: {formData},
url: '{{route("fileController.sendFiles")}}',
success: function(response) {
console.log(response);
},
error: function(response){
console.log(response);
}
});
Here's the route
Route::post('/sendFiles', ['uses' => 'FileController#sendFiles'])->name('fileController.sendFiles');
And the controller
public function sendFiles(Request $request)
{
//$data = json_decode($request->input('formData'), true);
//return $request->input('allFiles');
$data = json_decode($request->input('formData'), true);
return $data['allFiles'];
}
However, I get this error
"message": "Undefined index: allFiles"
When I check the contents of $request, I can see that allFiles array is clearly there, but how do I access it?
P.S. I've tried changing the second param when decoding to false, there's no difference.
$request data array
First of all your request data is simple array of objects. So you cannot index it with "allFiles".
Second since we have multiple objects with attribute name="allFiles[]", what you can do is filter those objects and return the values of it. (I don't know how are you going to use it, but this is how the code looks)
public function sendFiles(Request $request)
{
//$data = json_decode($request->input('formData'), true);
//return $request->input('allFiles');
$data = json_decode($request->input('formData'), true);
//filter all allFiles object
$allFiles = array_filter($data, function($obj){
if(isset($obj->name)){
return $obj->name=="allFiles[]";
}
return false;
});
//get values for all the filtered objects
$allFilesValues = array_map(function($obj){ return $obj->value; }, $allFiles);
return $data['allFiles'];
}
Let me know if this works for you.

Loading data in twig from controller using AJAX in symfony 3.4

i am trying to load data in twig from controller using AJAX ,
this is my controller action:
public function ajaxAction(Request $request) {
$students = $this->getDoctrine()
->getRepository('techeventBundle:event')
->findAll();
if ($request->isXmlHttpRequest() || $request->query->get('showJson') == 1) {
echo "request successfull";
$jsonData = array();
$idx = 0;
foreach($students as $student) {
$temp = array(
'name' => $student->getTitre(),
'address' => $student->getDescription(),
);
$jsonData[$idx++] = $temp;
}
return new JsonResponse($jsonData);
} else {
return $this->render('#reservation/Default/ajax.html.twig');
}
}
this is my twig file :
<!-- test Ajax --->
<button id="loadstudent">load events</button>
<div id="student">
<div id="name"></div>
<div id="address"></div>
</div>
<!-- test Ajax --->
<script language = "javascript"
src = "https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script language = "javascript">
$(document).ready(function(){
$("#loadstudent").on("click", function(event){
$.ajax({
url: '/student/ajax',
type: 'POST',
dataType: 'json',
async: true,
success: function(data, status) {
var e = $('<tr><th>Name</th><th>Address</th></tr>');
$('#student').html('');
$('#student').append(e);
for(i = 0; i < data.length; i++) {
student = data[i];
var e = $('<tr><td id = "name"></td><td id = "address"></td></tr>');
$('#name', e).html(student['name']);
$('#address', e).html(student['address']);
$('#student').append(e);
alert('Ajax request success');
}
},
error : function(xhr, textStatus, errorThrown) {
alert('Ajax request failed.');
}
});
});
});
</script>
let me describe to you the problem , when i click on the button ("#loadstudent") it shows up the 'Ajax request failed ' alert , added to that if you have seen in my action code i have added echo "request successfull"; after that :
if ($request->isXmlHttpRequest() || $request->query->get('showJson') == 1) {
it's not displaying that , which means that it's not getting into the condition ! help please i am stuck in this problem since one week ,
Add a route name in the controller #Route("/student/ajax", name="get-students")
Example:
/**
* #Route("/student/ajax", name="get-students")
*/
public function ajaxAction(Request $request) {
if ($request->isXmlHttpRequest() || $request->query->get('showJson') == 1) {
$jsonData = array(
array(
'name' => 'name1',
'address' => 'addres1',
),
array(
'name' => 'name2',
'address' => 'addres2',
),
);
return new JsonResponse($jsonData);
} else {
return $this->render('#reservation/Default/ajax.html.twig');
}
}
Now, in $.ajax send the request to route name url: "{{ path('get-students') }}"
<script language = "javascript">
$(document).ready(function () {
$("#loadstudent").on("click", function (event) {
$.ajax({
url: "{{ path('get-students') }}",
type: 'POST',
dataType: 'json',
async: true,
success: function (data, status) {
var e = $('<tr><th>Name</th><th>Address</th></tr>');
$('#student').html('');
$('#student').append(e);
for (i = 0; i < data.length; i++) {
student = data[i];
var e = $('<tr><td id = "name"></td><td id = "address"></td></tr>');
$('#name', e).html(student['name']);
$('#address', e).html(student['address']);
$('#student').append(e);
alert('Ajax request success');
}
},
error: function (xhr, textStatus, errorThrown) {
console.log(xhr, textStatus, errorThrown);
alert('Ajax request failed.');
}
});
});
});
</script>
Twig file output:
Name Address
name1 addres1
name2 addres2

Auto display results using json

Currently i'm using json to auto display my reuslt, but i got error say json_encode(): type is unsupported, encoded as null, and i think my problem is view, when i choose in name in dropdown i gives an error json_encode(): type is unsupported, encoded
Model
function get_address($name) {
$vendres = array('name' => $name);
$this->db->select('address');
$this->db->where($vendres);
$this->db->distinct();
$result = $this->db->get('profile');
if($result->num_rows() > 0){
foreach($result->result_array() as $row){
echo $row['address'];
}
}
return $result;
}
Controller
function address() {
$name=$this->input->post('name');
$this->load->model('default/M_profile');
$data['address'] = $this->M_vendor->get_address($name);
$this->output->set_output(json_encode($data));
//echo $data;
return;
}
in view i use dropdown.
$(document).ready(function () {
$('#profile select').change(function () {
var add = $(this).text();
$.ajax({
url: "<?php echo base_url();?>admin/profile/address",
method: "POST",
data: {profile: add},
success: function(add) {
$('#address').val(add);
}
})
});
});
<select name="test">....</select>
You have a lots of errors:
1.In ajax it should be type:'POST'.Not method:'POST'.
2.In controller it should be $this->input->post('profile')
3.In model just return your data using result_array().
MODEL:
function get_address($name) {
$vendres = array('name' => $name);
$this->db->select('address');
$this->db->where($vendres);
$this->db->distinct();
$result = $this->db->get('profile');
if($result->num_rows() > 0){
return $result->result_array();
}
}
}
Controller:
function address() {
$name=$this->input->post('profile');
$this->load->model('default/M_profile');
$data = $this->M_vendor->get_address($name);
echo json_encode($data);
}
View:(Ajax):
<script type="text/javascript">
$(document).ready(function () {
$('#profile select').change(function () {
var add = $(this).text();
$.ajax({
url: "<?php echo base_url('admin/profile/address');?>",
type: "POST",
data: {profile: add},
success: function(add) {
var data = JSON.parse(add);//parse response to convert into onject
console.log(data);//see your result in console
alert(data[0].address);
}
})
});
});
</script>
<select name="test">....</select>
I hope it helps you a lot.
you are echoing the result instead of returning
function get_address($name) {
$vendres = array('name' => $name);
$this->db->select('address');
$this->db->where($vendres);
$this->db->distinct();
$result = $this->db->get('profile');
if($result->num_rows() > 0){
foreach($result->result_array() as $row){
$result[] = $row['address'];
}
}
return $result;
}

JSON to HTML (Codeigniter)

public function getCrew(){
$search = $this->input->post('name');
if($this->input->post('ajax') && (!empty($search))){
$result = $this->model->getNames($search);
foreach($result as $r){
echo json_encode($r);
}
}
}
$(document).ready(function(){
$('#getMem').keyup(function(e){
var name = {
ajax: 1,
name: $('#getMem').val()
}
$.ajax({
url: 'work/getCrew',
type: 'POST',
data: name,
dataType: 'json',
success: function(data){
$('#freshMem').html(data.first_name);
},
error: function(){
alert('Error.');
}
});
});
});
This works fine if the result from database returns only one row, if more than one generates error, can anyone please tell me how to solve this
Use the Output class to tell the browser that JSON is being returned. The problem is that you are json_encodeing multiple objects in your foreach loop. Just json_encode the array returned from your model
public function getCrew(){
$search = $this->input->post('name');
if($this->input->post('ajax') && (!empty($search))){
$result = $this->model->getNames($search);
$this->output
->set_content_type('application/json')
->set_output(json_encode(array("response" => $result)));
}
}
$(document).ready(function(){
$('#getMem').keyup(function(e){
var name = {
ajax: 1,
name: $('#getMem').val()
}
$.ajax({
url: 'work/getCrew',
type: 'POST',
data: name,
dataType: 'json',
success: function(data)
{
var __html = '';
$.each(data.response, function (a, b)
{
__html += '<p>'+b.first_name+'</p>';
});
$('#freshMem').html(__html);
},
error: function()
{
alert('Error.');
}
});
});
});
Try this:
$.ajax({
url: 'work/getCrew',
type: 'POST',
data: name,
dataType: 'json',
success: function(data){
json_data = $.parseJSON(data);
$.each(json_data, function(i,item){
$('#freshMem').append(item.first_name);
});
},
error: function(){
alert('Error.');
}
});
You have to iterate over returned array.
Also you need to change your controller code:
public function getCrew(){
$search = $this->input->post('name');
if($this->input->post('ajax') && (!empty($search))){
$result = $this->model->getNames($search);
// assuming that $result is array...
$json = json_encode($result);
echo $json;
/*foreach($result as $r){
echo json_encode($r);
}*/
}
}