404 not found when passing variable to route in laravel - php

I'm trying to run an ajax call, and i keep getting
http://127.0.0.1:8000/books/rate/2 404 (Not Found)
So it gets the id well, but showing a 404 error.
route.php
Route::post('rate/{book_id}','BookController#rate')->name('rate');
main.js
$('#sub').submit(function(e){
var owl = $(this).attr("data");
var route = JSON.parse(owl);
$.ajax({
type:"POST",
url:"rate/" + route.id,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
success:function(res){
console.log("owls");
}
});
event.preventDefault();
});
controller(book controller)
public function rate(Request $request, $book_id)
{
$book = Book::find($book_id);
$rating = $book->ratings()->where('user_id', auth()->user()->id)->first();
if(is_null($rating)){
$ratings = new Rating();
$ratings->rating = $request['rating'];
$ratings->user_id = auth()->user()->id;
$book->ratings()->save($ratings);
return json_encode($book);
}
else{
return redirect()->back()->with("status", "You already left a review");
}
}
HTML
<form id="sub" data= "{{ $book }}">
{!! csrf_field() !!}
<div id="rateYo" data-rateyo-rating="{{ $book->userSumRating or 0}}"> ></div>
<input name="rating" value='{{ $book->userSumRating or 0 }}' type="hidden" id="val">
<button type="submit" class="btn btn-primary mt-2">submit</button>
</form>

You are using ajax post so instead redirect use json response like this
public function rate(Request $request, $book_id)
{
$book = Book::find($book_id);
$rating = $book->ratings()->where('user_id', auth()->user()->id)->first();
if(is_null($rating)){
$ratings = new Rating();
$ratings->rating = $request['rating'];
$ratings->user_id = auth()->user()->id;
$book->ratings()->save($ratings);
return json_encode($book);
}
else{
return response()->json(['status' => "You already left a review"]);
}
}
Add try this javascript code
$.ajax({
type:"POST",
url:"http://127.0.0.1:8000/rate/" + route.id,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data:{rating: $('#val').val()},
success:function(res){
console.log("owls");
}
});

I think you need a change in javascript like below
$('#sub').submit(function(e){
var owl = $(this).attr("data");
var route = JSON.parse(owl);
$.ajax({
type:"POST",
url:"http://127.0.0.1:8000/rate/" + route.id,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
success:function(res){
console.log("owls");
}
});
event.preventDefault();
});
This is because in your URL you are getting books before rate/{rate_id} thats why it is showing error of 404 page not found!

Just Use It Like This :-
$.ajax({
type:"POST",
url:"{{url('rate/')}}" + route.id,
headers: {
'X-CSRF-TOKEN': {{ csrf_token() }}
},
success:function(res){
console.log("owls");
}
});

Related

Laravel Update Database with ajax

Hey guys I'm using laravel 5.7 and I'm attempting to make a ajax post request to update my database. The ajax would post based on a checkbox on change function. Example if i toggle off the checkbox it would send a request and update my status to Inactive in my User table. After attempting it, i had an error of 405 (Method Not Allowed). Anyone able to note what am i doing wrong? Sorry if there are some wrong codes or syntax in my codes as I'm very new to Ajax. Any help would be appreciated.
Ajax
$(document).ready(function(){
$.ajax({
type:'get',
url:'{!!URL::to('findStatus')!!}',
success:function(data){
for(var i=0;i<data.length;i++){
var checkBox = document.getElementById('switch-'+data[i].u_id);
console.log(checkBox);
if(data[i].status == "Active"){
$('#switch-'+data[i].u_id).prop('checked',true);
}
else if(data[i].status == "Inactive")
{
$('#switch-'+data[i].u_id).prop('checked',false);
}
$('#switch-'+data[i].u_id).change(function(){
$.ajax({
type: "POST",
url : '{!!URL::to('admin/{admin}')!!}',
success:function(data){
console.log(data);
}
});
});
}
},
error:function(data){
console.log('ERROR');
}
});
});
Route
Route::resource('admin','AdminController'); << I'm using the update method from the resource controller
Controller
public function update(Request $request, $id)
{
$user = User::find($id);
if($user->status == "Active"){
$user->status = "Inactive";
$user->save();
}else{
$user->status = "Active";
$user->save();
}
return response()->json($user);
}
Form
{!!Form::open(array('action'=>['AdminController#update',$item->u_id],'method'=>'POST','id'=>'update'))!!}
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="u_id" id="u_id" value="{{$item->u_id}}">
<label class="custom-control custom-checkbox">
<input type="checkbox" id="switch-{{$item->u_id}}" class="custom-control-input">
<span class="custom-control-indicator"></span>
</label>
{{-- <button class="btn btn-primary">Update</button> --}}
{{Form::hidden('_method','PUT')}}
{!!Form::close()!!}
UPDATE
I have managed to "pass" the u_id to my post request by getting the id through target.id and splitting it with -. It is not the most elegant way but it works. But now im getting an error
POST http://manageme.test/admin/%7B2%7D 500 (Internal Server Error)
Here is what i have updated in my codes.
$('#switch-'+data[i].u_id).change(function(e){
console.log(e.target.id);
var s = e.target.id;
var split = s.split('-')[1];
$.ajax({
type: "POST",
url: `{!!url('admin/')!!}/{${split}}`,
data: { _token: "{{ csrf_token() }}", _method: "PUT" },
success:function(data){
console.log(data);
}
});
});
these are inside my update controller
public function update(Request $request, $id)
{
$user = User::find($id);
if($user->status == "Active"){
$user->status = "Inactive";
$user->save();
}else{
$user->status = "Active";
$user->save();
}
return response()->json($user);
}
I have also looked at the error inside the network tab of the dev tools the error message from laravel is message: "Trying to get property 'status' of non-object". I think it cant find any $user inside the update method
Instead of:
"{!!URL::to('admin/{admin}')!!}"
write :
`{!!url('admin/')!!}/${data[i].u_id}`
and add _token and _method params to your ajax data
and write like this:
$(document).ready(function () {
$.ajax({
type: 'get',
url: '{!!url('findStatus')!!}',
success: function (data) {
data.forEach(d => {
console.log(d);
if (d.status == "Active") {
$(`#switch-${d.u_id}`).prop('checked', true);
}
else if (d.status == "Inactive") {
$(`#switch-${d.u_id}`).prop('checked', false);
}
$(`#switch-${d.u_id}`).change(function () {
console.log(d);
//changed###########
$.ajax({
type: 'POST',
url: `{!!url('admin/')!!}/${d.u_id}`,
data: { _token: "{{ csrf_token() }}", _method: "PUT" },
success: function (data) {
console.log(data);
}
});
//###################
});
});
},
error: function (data) {
console.log('ERROR');
}
});
});
Solution
I managed to fix it the problem was coming from the route trying to pass the u_id of the user and finding the user's data. So instead of typing the url inside, i made a variable to pass the route and u_id together. Here are the codes
Ajax
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type:'get',
url:'{!!url('findStatus')!!}',
success:function(data){
for(var i=0;i<data.length;i++){
var checkBox = document.getElementById('switch-'+data[i].u_id);
if(data[i].status == "Active"){
$('#switch-'+data[i].u_id).prop('checked',true);
}
else if(data[i].status == "Inactive")
{
$('#switch-'+data[i].u_id).prop('checked',false);
}
$('#switch-'+data[i].u_id).change(function(e){
var s = e.target.id;
var split = s.split('-')[1];
var url = '{{route('admin.update','split')}}';
$.ajax({
type: 'POST',
url: url,
data: { _token: "{{ csrf_token() }}", _method: "PUT" ,u_id: split},
success: function(data) {
console.log(data['message']);
}
});
});
}
},
error:function(data){
console.log('ERROR');
}
});
Update method
public function update(Request $request, $id)
{
$user = User::find($request['u_id']);
if($user->status == "Active")
{
$user->status = "Inactive";
$user->save();
return response()->json(['message' => 'Update to Inactive']);
}else{
$user->status = "Active";
$user->save();
return response()->json(['message' => 'Update to Active']);
}
}
DONT forget to add the meta tag onto the document header for csrf token
<meta name="csrf-token" content="{{ csrf_token() }}">

how to fix MethodNotAllowedHttpException in laravel

i'm creating function delete in laravel and here is my Controller
public function removePetitions($id)
{
$rm = Petitions::find($id);
$rm->delete();
return ['status' => true];
}
and here is my route
Route::post('/delete/petition/{id}','Admin\PetitionController#removePetitions')->name('admin.delete');
when i click button delete in view it show MethodNotAllowedHttpException. anyone solve that??? thank u
If i understand your problem You are looking for this kin of stuff
Your anchor tag here look like this:-
Del
And route looklike this :-
Route::post('/delete/petition','Admin\PetitionController#removePetitions');
And now ajax code :-
<meta name="csrf-token" content="{{ csrf_token() }}" /> // add in head tag
$.ajaxSetup({
headers:{
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$(document).on('click','.btn-del-petition',function(){
var id = $(this).attr('data-id');
$.ajax({
type: 'post',
url: 'delete/petition',
data: {id :id},
success:function(resp){
alert(resp);
//Delete that deleted row with jquery
},
error:function(){
alert('Error');
}
})
})
Now your function :-
public function removePetitions(Request $request)
{
if($request->ajax()){
$data = $request->all();
$rm = Petitions::find($data['id']);
$rm->delete();
return ['status' => true];
}
}
Hope it helps!

How to delete record in laravel via ajax

I know there are similar questions relating to this issue, but I have tried my copy after those with the right answer, yet still to no avail.
I keep getting this error:
BadMethodCallException Method delete does not exist. in Macroable.php (line 74)
To be quick, here is my controller:
public function destroy(Subject $subject)
{
//
$response = array();
$modal = new Subject;
$modal = Subject::find($subject);
if ( $modal->delete() ) {
$response['success'] = '<b>'.$modal->name.'</b>'.' successfully deleted';
$response['subject'] = $modal;
}
return \Response::json($response);
}
Here is my route:
Route::delete('/subjects/delete/{subject}', 'SubjectsController#destroy');
Here is my view:
<td>
<a data-token="{{ csrf_token() }}" id="delete" data-id="{{$subject->id}}" data-toggle="tooltip" title="Edit" href="/subjects/{{$subject->id}}" role="button"><i class="glyphicon glyphicon-trash text-danger"></i></a>
</td>
and last my scripts:
$(document).on('click', '#delete', function(event) {
event.preventDefault();
/* Act on the event */
// id of the row to be deleted
var id = $(this).attr('data-id');
var token = $(this).data("token");
console.log(id);
// row to be deleted
var row = $(this).parent("td").parent("tr");
var message = "subject";
bootbox.dialog({
message: "Are you sure you want to Delete this "+message+"?",
title: "<i class='glyphicon glyphicon-trash'></i> Delete !",
buttons: {
success: {
label: "No",
className: "btn-success",
callback: function() {
$('.bootbox').modal('hide');
}
},
danger: {
label: "Delete!",
className: "btn-danger",
callback: function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'DELETE',
url: '/subjects/delete/'+id,
data: {
"id": id,
"_method": 'DELETE',
"_token": token
}
})
.done(function(response){
bootbox.alert(response.success);
//removing the row that have been deleted
jQuery(row).fadeOut('slow');
})
.fail(function(){
bootbox.alert('Something Went Wrong .... Please contact administrator');
})
}
}
}
});
});
Here is what I get when I don php artisan route:list
I don't know the technical details of why it is working this way but it seems the the problem was coming from my controller destroy method. So, this was all I had to do:
controller code:
public function destroy($subject)
{
//
$response = array();
$modal = new Subject;
$modal = Subject::find($subject);
if ( $modal->delete() ) {
$response['success'] = '<b>'.$modal->name.'</b>'.' successfully deleted';
$response['subject'] = $modal;
}
return \Response::json($response);
}
script:
callback: function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'DELETE',
url: '/subjects/delete/'+id,
data:{"id": id, "_method": 'DELETE'}
})
.done(function(response){
bootbox.alert(response.success);
//removing the row that have been deleted
jQuery(row).fadeOut('slow');
})
.fail(function(){
bootbox.alert('Something Went Wrong .... Please contact administrator');
})
}
route:
Route::delete('/subjects/delete/{subject}','SubjectsController#destroy');
The main thing for me was to remove the Subject from the destroy() parameter and it work.
If any of you know why it's working that please provide and explanation so that I can understand it too. Thanks!!
Change the type in your ajax call to POST, the _method field in the data object is all that is needed. This is how your ajax call should look. Laravel "fakes" the DELETE method by using the _method field to determine the http verb.
$.ajax({
type: 'POST',
url: '/subjects/delete/'+id,
data: {
"_method": 'DELETE',
"_token": token
}
})
.done(function(response){
bootbox.alert(response.success);
//removing the row that have been deleted
jQuery(row).fadeOut('slow');
})
.fail(function(){
bootbox.alert('Something Went Wrong .... Please contact administrator');
})

Laravel ajax internal servor 500 (internal server-error)

I have a shopping cart which is stored in session and I want to refresh the session without reloading the page
I have tried this:
View:
Add to cart
<script>
$(document).ready(function() {
$('#product').click(function(event) {
event.preventDefault();
let url = "{{ route('add-to-cart') }}";
let id = $(this).data('id');
$.ajax({
url: url,
type: 'POST',
data: {product_id: id, _token: "{{ Session::token() }}"}
})
.done(function() {
console.log("success");
})
.fail(function() {
console.log("error");
})
});
});
Route:
Route::post('/add-to-cart', 'ProductsController#addToCart')->name('add-to-cart');
ProductsController:
public function addToCart(Request $request)
{
if ($request::ajax()) {
$id = $request->product_id;
$product = Product::find($id);
if (Session::has('products')) {
$products = Session::get('products');
$products[] = $product;
Session::put('products', $products);
}
else {
$products = array($product);
Session::put('products', $products);
}
return response()->json();
}
}
And when I click add to cart it gives 500 (Internal Server Error) in the console
You're accessing the ajax() method statically (using ::), when you should be using -> instead:
if ($request->ajax()) {
Using the Laravel log file
As mentioned in the comments, Laravel is probably telling you this in storage/logs/laravel.log, complete with a long call-stack trace (the lines that you mentioned, beginning with "#38" and "#39"). Just scroll up to before "#1" and you'll find your culprit.
Laravel doesn't allow without passing X-CSRF-TOKEN,
following is my working example hope it helps you.
Route :
Route::post('block-user','UserController#BlockUser');
Now you need to add ajax setup before your ajax call so in
blade.php :
Add this in header
<meta name="csrf-token" content="{{ csrf_token() }}" />
My script like :
<script>
//Ajax setup
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
//Ajax call
$(".blockuser").bootstrapSwitch();
$('.blockuser').on('switchChange.bootstrapSwitch', function () {
var userid = $('#userid').val();
$.ajax({
url:'/block-user',
data:{user_id : userid},
type:'post',
success: function(data){
alert(data);
}
});
});
</script>
Controller :
public function BlockUser(Request $request)
{
$userid = $request->get('user_id');
//perform operation
}

Laravel - Toggle value in database with checkbox and ajax

I want to toggle a boolean value in my table with a checkbox through jquery and ajax.
So whenever a user ticks the the checkbox it should toggle the value in table.
So far i came up with this but i need help:
$(document).ready(function(){
$("input:checkbox").change(function() {
var isChecked = $("input:checkbox").is(":checked") ? 1:0;
$.ajax({
type:'POST',
url:'/activation',
headers: {'X-CSRF-TOKEN': '{{ csrf_token() }}' },
data: $('.checkbox').serialize(),
success:function(data){
}
});
});
});
#andre's answer is correct but
if($user->active == 1){
$user->active = 0;
} else {
$user->active = 1;
}
this part can be done by a single line
$user->active = !$user->active;
The only thing I'd modify would be returning an answer to the ajax call to let it know what's happening.
public function activation(Request $request)
{
$user = User::findOrFail($request->user_id);
if($user->active == 1){
$user->active = 0;
} else {
$user->active = 1;
}
return response()->json([
'data' => [
'success' => $user->save(),
]
]);
}
And now in the front-end part:
$(document).ready(function(){
$("input:checkbox").change(function() {
var user_id = $(this).closest('tr').attr('id');
$.ajax({
type:'POST',
url:'/activation',
headers: {'X-CSRF-TOKEN': '{{ csrf_token() }}' },
data: { "user_id" : user_id },
success: function(data){
if(data.data.success){
//do something
}
}
});
});
});
jQuery Ajax documentation
in model create a method
function toggleActive ()
{
$this->active!=(int)$this->active;
return $this;
}
in controller
$model->toggleActive()->save();

Categories