DELETE 405 (Method Not Allowed) - Laravel with Axios - laravel

Basically i am trying to delete a row using axios, but i keep getting DELETE 405 (Method Not Allowed)
This is my api route for delete:
Route::delete('/vehicles/{id}', [VehiclesController::class, 'destroy']);
In the controller:
public function destroy($id)
{
$vehicleDelete = Vehicle::findOrFail($id);
$vehicleDelete->delete();
return response()->json([
"status" => true
], 200);
}
The button in the front-end:
<button class = 'btn btn-danger' onclick = "deleteBtn(${item.id})">Delete</button>
I tried using console.log to see if the i get the correct id and it does get the correct.
And here is the axios function:
const deleteBtn = (id) => {
axios.delete("api/vehicles/" + id)
.then(response => {
console.log(id);
})
}

After trying out almost everything here is the solution that i randomly came with:
API Route:
Route::delete('/vehicles/{id}', [VehiclesController::class, 'destroy']);
Destroy method in the controller:
public function destroy($id)
{
$vehicle = Vehicle::find($id);
if(!$vehicle) {
return response()->json(["error" => "Vehicle does not exist!!"]);
}
if($vehicle->delete()) {
return response()->json(["success" => "Vehicle deleted!!"]);
}
return response()->json(["error" => "Something bad happened!!"]);
}
front-end button:
<button class = 'btn btn-danger' onclick = "deleteBtn(${item.id})">Delete</button>
And finally, the javascript function:
const deleteBtn = (id) => {
axios.delete(API.url + (API.routes.deleteVehicles.replace("{id}", id)))
.then(response => {
vehicleTable.innerHTML = "";
drawVehicles();
})
}
For reference here is the API object:
const API = {
url: 'http://127.0.0.1:8000/api',
routes: {
getVehicles: '/vehicles',
deleteVehicles: '/vehicles/{id}',
createVehicles: '/vehicles'
}
}

Related

How to solve SyntaxError: Unexpected token < in JSON at position 0 in Paypal checkout in Laravel

I am doing Paypal integration in Laravel. I have used composer require srmklive/paypal to install the srmklive/paypal package in this project.
When I press the PayPal button, I get this error:
Here is my code:
code from blade file:
paypal.Buttons({
createOrder: function(data, actions) {
return fetch('api/paypal/order/create/', {
method: 'post',
body:JSON.stringify({
"value":100
})
}).then(function(res) {
return res.json();
}).then(function(orderData) {
return orderData.id;
});
},
onApprove: function(data, actions) {
return fetch('/api/paypal/order/capture/', {
method: 'post',
body: JSON.stringify({
orderID: data.orderID
})
}).then(function(res) {
return res.json();
}).then(function(orderData) {
var errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
return actions.restart();
}
if (errorDetail) {
var msg = 'Sorry, your transaction could not be processed.';
return alert(msg); // Show a failure message (try to avoid alerts in production environments)
}
});
}
}).render('#paypal-button-container');
code from paymentController:
class PaymentController extends Controller
{
public function create(Request $request){
$data = json_decode($request->getContent(), true);
$provider = \PayPal::setProvider();
$provider->setApiCredentials(config('paypal'));
$token = $provider->getAccessToken();
$provider->setAccessToken($token);
$price = Plan::getSubscriptionPrice($data['value']);
$description = Plan::getSubscriptionDescription($data['value']);
$order = $provider->createOrder([
"intent" => "CAPTURE",
"purchase_units" => [
[
"amount" => [
"currency_code" => "USD",
"value" => $price
],
"description" => $description
]
]
]);
return response()->json($order);
}
public function capture(Request $request) {
$data = json_decode($request->getContent(), true);
$orderId = $data['orderID'];
$provider = \PayPal::setProvider();
$provider->setApiCredentials(config('paypal'));
$token = $provider->getAccessToken();
$provider->setAccessToken($token);
$result = $provider->capturePaymentOrder($orderId);
return response()->json($result);
}
}
How can I solve this error?
The route api/paypal/order/create/ is returning/outputting text that is not JSON, such as an HTML error page or something else that begins with an HTML tag.
The route must only output JSON, and must contain a valid id from the PayPal API.

how to solve paypal login tab missing when integrate with paypal

I want to do paypal integration in Laravel. I have use composer require srmklive/paypal to install the srmklive/paypal package for my project. I get 404 error when I want to press the PayPal button. The popup paypal login tab will missing. Then I inspect the network I get the error like image given.
Here is my code:
class PaymentController extends Controller
{
public function create(Request $request){
$data = json_decode($request->getContent(), true);
$provider = \PayPal::setProvider();
$provider->setApiCredentials(config('paypal'));
$token = $provider->getAccessToken();
$provider->setAccessToken($token);
$plan = $provider->createOrder([
"intent" => "CAPTURE",
"purchase_units" => [
[
"amount" => [
"currency_code" => "USD",
"value" => "30"
],
"description" => "Item 1"
]
]
]);
return response()->json($plan);
}
public function capture(Request $request) {
$data = json_decode($request->getContent(), true);
$orderId = $data['orderID'];
$provider = \PayPal::setProvider();
$provider->setApiCredentials(config('paypal'));
$token = $provider->getAccessToken();
$provider->setAccessToken($token);
$result = $provider->capturePaymentOrder($orderId);
return response()->json($result);
}
}
Here is the code from blade file
paypal.Buttons({
createOrder: function(data, actions) {
return fetch('api/paypal/order/create/', {
method: 'post',
body:JSON.stringify({
"value":30
})
}).then(function(res) {
return res.json();
}).then(function(orderData) {
return orderData.id;
});
},
onApprove: function(data, actions) {
return fetch('/api/paypal/order/capture/', {
method: 'post',
body: JSON.stringify({
orderID: data.orderID
})
}).then(function(res) {
return res.json();
}).then(function(orderData) {
var errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
return actions.restart(); // Recoverable state, per:
}
if (errorDetail) {
var msg = 'Sorry, your transaction could not be processed.';
return alert(msg);
}
});
}
}).render('#paypal-button-container');
The error show like image given.
Does anyone know how to solve it?
Does the route api/paypal/order/create/ exist on your server? From the error message, it's returning a 404.
The route must exist (no 404) and successfully output a JSON response with an id obtained from the PayPal API.

Redirect in inertia js and jetstream in javascript code

I want to be redirected to single question page after creation of question
summitQuestion(){
this.question_button = true
axios.post('/api/question/ask', {
'title' : this.question.title,
'body' : this.question.body,
'tags' : this.tags,
'user_id' : this.$page.props.user.id
}).then(response=>{
this.question_button = false
console.log(response.data)
}).catch(error=>{
this.question_button = false
console.log(error.response.data.errors)
if(error.response.data.errors){
this.title_errors = error.response.data.errors.title
this.body_errors = error.response.data.errors.body
}
})
},
I have this function I want after the success of the request to redirect I a spa way without page reloading to question single page I am using inertia js and jetstream my laravel router is below
Route::middleware(['auth:sanctum', 'verified'])->get('/question/{question}', 'App\Http\Controllers\QuestionController#show')->name('question-single');
Simply use the visit method on the inertia like shown below.
this.$inertia.visit(route('question-single'), { method: 'get' });
If you got everything correct from your code above remaining the redirection without your page reloading, then I guess the modification of your code will be the sample as folows;
summitQuestion(){
this.question_button = true
axios.post('/api/question/ask', {
'title' : this.question.title,
'body' : this.question.body,
'tags' : this.tags,
'user_id' : this.$page.props.user.id
}).then(response=>{
this.question_button = false
// console.log(response.data)
this.$inertia.visit(route('question-single'), { method: 'get', data: response.data });
}).catch(error=>{
this.question_button = false
console.log(error.response.data.errors)
if(error.response.data.errors){
this.title_errors = error.response.data.errors.title
this.body_errors = error.response.data.errors.body
}
})
},
You can make reference to this by visiting The Official Inertiajs Website
If you are using Inertia, you are supposed to create a form with v-model linked to fields. Add to that a button of type submit that call your method (see below the method example).
<form #submit.prevent="submitQuestion">
<input type="text" v-model="form.title">
<button type="submit"></button>
</form>
<script>
export default {
data() {
return {
form: this.$inertia.form({
title: this.question.title,
body: this.question.body,
tags: this.tags,
user_id: this.$page.props.user.id,
}, {
bag: 'default',
}),
}
},
methods: {
summitQuestion: function() {
this.form.post('/api/question/ask');
},
}
};
</script>
The redirection can be done directly on your controller method.
class QuestionController extends Controller
{
public function create(Request $request) {
// Create your question
return redirect()->route('your.route');
}
}

On get request why do I get back the blade view, when I should get data from the database instead?

I a have the following get request, which is executed on mounted().
In some weird mysterious ways, I get back my main view app.blade as a response when I am clearly requesting some data from the database.
Can someone spot what I messed up?
My get request on the front-end:
mounted() {
this.getProjectRequests();
},
methods: {
getProjectRequests: function() {
var self = this;
let clientId = this.$route.path.substring(
this.$route.path.lastIndexOf("/") + 1
);
axios({
method: "get",
url: "/get-project-requests/" + clientId
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
// TODO error handling
});
}
}
My route:
Route::get('/get-project-requests/{client_id}',
'SinglePageController#getProjectRequests');
And my controller method:
public function getProjectRequests($clientId) {
try {
$projectRequests = ProjectRequest::where('client_id',
$clientId)->value('name');
return response()->json( [
'success'=> true,
'projectRequests' => $projectRequests
]);
} catch(\Exception $e){
return ['success' => false, 'message' => 'getting
project requests failed'];
}
}
I think this ProjectRequest::where('client_id', $clientId)->value('name'); giving exception.
Either you check your laravel.log inside storage/logs folder or change that method into
// Not working on eloquent model
$valueOject = ProjectRequest::where('client_id',$clientId)->value('name');
// DB facade its working. Change to this method
$valueOject = DB::table('{your_table}')->where('client_id', $clientId)->value('name');
dd($valueOject);

Pusher authentication not working as expected

I have made a project with Laravel and react. There is a react component defined for video chat. Video is working but I am having issues with presence_auth(), basically getting the error with response 500 ()
Call to undefined method Pusher\Pusher::presence_auth()
Following is my web routes file:
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::post('/pusher/auth', 'HomeController#authenticate');
The HomeController where I am getting this error:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use \Pusher\Pusher;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return view('home');
}
public function authenticate(Request $request){
$socketId = $request->socket_id;
$channelName = $request->channel_name;
$pusher = new Pusher('7525d88e2baa6d08b175', 'c25081ca96b9033e941c', '523589', [
'cluster' => 'ap1',
'encrypted' => true
]);
$presence_data = ['name' => auth()->user()->name];
$key = $pusher->presence_auth($channelName, $socketId, auth()->id(), $presence_data);
return response($key);
}
}
And finally my App.js file with the components:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import MediaHandler from '../MediaHandler';
import Pusher from 'pusher-js';
import Peer from 'simple-peer';
const APP_KEY = '7525d88e2baa6d08b175';
export default class App extends Component {
constructor(){
super();
this.state = {
hasMedia: false,
otherUserId: null
};
this.user = window.user;
this.user.stream = null;
this.peers = {};
this.mediaHandler = new MediaHandler();
this.setupPusher();
this.callTo = this.callTo.bind(this);
this.setupPusher = this.setupPusher.bind(this);
this.startPeer = this.startPeer.bind(this);
}
componentWillMount(){
this.mediaHandler.getPermissions()
.then((stream) => {
this.setState({hasMedia: true});
this.user.stream = stream;
try{
this.myVideo.srcObject = stream;
} catch(e) {
this.myVideo.src = URL.createObjectURL(stream);
}
this.myVideo.play();
})
}
setupPusher(){
this.pusher = new Pusher(APP_KEY, {
authEndpoint: '/pusher/auth',
cluster: 'ap1',
auth: {
params: this.user.id,
headers: {
'X-CSRF-Token': window.csrfToken
}
}
});
this.channel = this.pusher.subscribe('presence-video-channel');
this.channel.bind(`client-signal-${this.user.id}`, (signal) => {
let peer = this.peers[signal.userId];
if(peer == undefined){
this.setState({otherUserId: signal.userId});
peer = this.startPeer(signal.userId, false);
}
peer.signal(signal.data);
});
}
startPeer(userId, initiator = true){
const peer = new Peer({
initiator,
stream: this.user.stream,
trickle: false
});
peer.on('signal', (data) => {
this.channel.trigger(`client-signal-${userId}`, {
type: 'signal',
userId: this.user.id,
data: data
});
});
peer.on('stream', (stream) => {
try{
this.userVideo.srcObject = stream;
} catch(e) {
this.userVideo.src = URL.createObjectURL(stream);
}
this.userVideo.play();
});
peer.on('close', () => {
let peer = this.peers[userId];
if(peer != undefined){
peer.destroy();
}
this.peers[userId] = undefined;
});
return peer;
}
callTo(userId){
this.peers[userId] = this.startPeer(userId);
}
render() {
return (
<div className="App">
{[1,2,3,4].map((userId) => {
return this.user.id != userId ? <button key={userId} onClick={() => this.callTo(userId)}>Call {userId}</button> : null
})}
<div className="video-container">
<video className="my-video" ref={(ref) => {this.myVideo = ref;}}></video>
<video className="user-video" ref={(ref) => {this.userVideo = ref;}}></video>
</div>
</div>
);
}
}
if (document.getElementById('app')) {
ReactDOM.render(<App />, document.getElementById('app'));
}
Everything else is working fine interms of stream but for some reason, presence_auth() function is not being identified.
So I had the same issue and i was able to solve it. my pusher php client was pusher/pusher-php-server "~3.0". The presence_auth() method is not available in this version of the library. I had to use the latest library which is version 5 and it worked seemlessly without any further modification. I just update the to the latest version.

Resources