So I'm trying to store data in my election_users table but making a POST request gives a "500 (Internal Server Error)" error. My object does return the right "election_id". I don't know what I'm doing wrong.
here's my method in my vue script:
methods: {
createVote: function () {
var itemId = this.$route.params.id
var input = this.newUserVoted
this.newUserVoted.election_id = itemId
this.$http.post('http://www.nmdad2-05-elector.local/api/v1/electionuser', input)
.then((response) => {
this.newUserVoted = {'election_id': itemId}
}).catch(e => {
console.log(e)
console.log(input)
})
}
},
my UsersController.php
public function store(Request $request)
{
$userVoted = new ElectionUser();
$userVoted->election_id = $request['election_id'];
$userVoted->user_id = Auth::id();
if ($userVoted->save()) {
return response()
->json($userVoted);
}
}
my routesApi.php
Route::post( 'electionuser', 'UsersController#store' );
My ElectionUser.php
class ElectionUser extends Model
{
// Relationships
// =============
protected $fillable = [
'election_id',
'user_id'
];
public function election()
{
return $this->belongsToMany(Election::class);
}
}
You need to add CSRF token:
https://laravel.com/docs/5.4/helpers#method-csrf-token
For example in the view
<script>
var csrf = '{{csrf_token()}}';
</script>
And in your script
var formData = new FormData();
formData.append('_token', csrf);
formData.append('input', this.newUserVoted);
this.$http.post('http://www.nmdad2-05-elector.local/api/v1/electionuser', formData)
Related
I have two pieces of code, the Front-end in React and the Bakc-end in Laravel, the problem is im calling the API to get an array of a SQL join but in the useEffect React Hook it doest get the info, but if i make a button to get it works, i don't know why the useEffect Hook isn't working properly
I partially solved the question by treating the response as an array but if you are sending more than 1 thing i still dont know what to do
I have this pieces of code
Laravel:
public function show($id)
{
$returned = response('El lote solicitado no existe', Response::HTTP_BAD_REQUEST);
$lote = DB::table('lotes')
->leftjoin('articulos', 'lotes.idArticulo', '=', 'articulos.id')
->select('lotes.idLote', 'lotes.idArticulo', 'lotes.cantidad', 'lotes.consumoPreferente', 'lotes.observaciones', 'articulos.descripcion')
->where('lotes.id', $id)
->get();
if($lote){
$returned = response($lote, Response::HTTP_OK);
}
return $returned;
}
React:
const [lote, setLote] = useState([])
useEffect(() => {
document.title = `Lote ${id}`
getLote()
}, [])
const { id } = useParams()
const getLote = async () => {
try {
const response = await axios.get(`${endpoint}/lote/${id}`)
setLote(response.data)
} catch (e) {
console.log(`Error ${e}`)
}
}
The problem is that lote isn't setting in the useEffect hook, but if i call the getLote function outside of it works.
Another issue is that if i change the laravel part to this works properly on the useEffect call:
I think the key is here, if i use the 'findOrFail' it works properly but if make a SQL query it doesn't, but if im using the async - await it should wait, rigth?
$lote = Lote::findOrFail($id);
if($lote ){
$returned = response($lote , Response::HTTP_OK);
}
return $returned;
Also to mention im ussing axios to make the calls, could it be the problem too?
Do you know what could be happening?
The first thing you need to do is to make sure that id is already defined in useEffect, so you need to re-write useEffect like this:
useEffect(() => {
if(!id) {
return;
}
document.title = `Lote ${id}`
getLote()
}, [id]);
also, I would recommend putting function in useCallback
const getLote = useCallback(async () => {
try {
const response = await axios.get(`${endpoint}/lote/${id}`)
setLote(response.data)
} catch (e) {
console.log(`Error ${e}`)
}
}, [id]);
It is crucial to add relevant dependencies in deps array.
I solved the question by doing an intermediate step
If the data that is being sended is only one object in the array
const [lote, setLote] = useState([])
useEffect(() => {
document.title = `Lote ${id}`
getLote()
}, [])
const { id } = useParams()
const getLote = async () => {
try {
const response = await axios.get(`${endpoint}/lote/${id}`)
setLote(response.data[0])
} catch (e) {
console.log(`Error ${e}`)
}
}
If the data that is being sended are more than one object in the array
const [lote, setLote] = useState([])
useEffect(() => {
document.title = `Lote ${id}`
getLote()
}, [])
const { id } = useParams()
const getLote = async () => {
try {
const response = await axios.get(`${endpoint}/lote/${id}`)
let newLote = response.data
setLote(newLote)
} catch (e) {
console.log(`Error ${e}`)
}
}
I don't know why this happens but this solution worked for me
I want to send POST data from NodeJS server (localhost:4000) to PHP symfony server (localhost:8000)
But every time when I'm trying to send it, I got always same result => empty array.
Here is my code:
NodeJS
var data = {
method: "disconnectFromGame",
};
var querystring = require("querystring");
var qs = querystring.stringify(data);
var qslength = qs.length;
var options = {
hostname: "http://localhost:8000",
port: 80,
path: "/game/api",
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': qslength
}
};
var buffer = "";
var req = http.request(options, function (res) {
res.on('data', function (chunk) {
buffer += chunk;
});
res.on('end', function () {
console.log(buffer);
});
});
req.write(qs);
req.end();
It works fine, debugger stop me at the specific breakpoint, so communication is OK, but $request has always empty parameters..
PHP Symfony 5
public function engineApi(Request $request) {
$user = $this->getUser();
if(!$user) {
return $this->redirectToRoute("app_login");
}
if (!$request->isXMLHttpRequest()) {
return $this->redirectToRoute("app_homepage_show");
}
$entityManager = $this->getDoctrine()->getManager();
$data = $request->request->all();
$api = new Api($data, $user, $entityManager);
return $api->processMethod();
}
Your script works :
How do you get the picture of your dump ? Because I think, this is where you made a mistake.
When you execute the NodeJs script, did you get a response from the Symfony server in your console ? Because if you put a dump() in your Symfony, you should have something like this (which is the raw view of html response with dump data from Symfony) :
Using a simple Ajax GET request to retrieve some data, it successfully checks if($request->ajax()) {} but then fails any validation because there is no data in the Request $request variable. This happens only on the production server, on localhost everything works fine.
The console shows the intended URL https://example.com/employeeInfo?id=1, then error 422 (Unprocessable Entity). Output from error: function(jqxhr, status, exception) { alert('Exception:', exception); } gives an empty alert message.
View
<script>
(function ($) {
$(document).ready(function() {
$(".team-pic").off("click").on("click", function() {
$id = $(this).data('id');
// Get data
$.ajax({
type: 'GET',
url: 'employeeInfo',
data: {'id':$id},
success: function(data){
var obj=$.parseJSON(data);
// Show output...
},
error: function(jqxhr, status, exception) {
alert('Exception:', exception);
}
});
});
});
}(jQuery));
</script>
Route
Route::get('/employeeInfo', 'EmployeeController#get');
Controller
public function get(Request $request) {
if($request->ajax()) {
$this->validate($request, [
'id' => 'required|integer',
]);
// Id
$employee = Employee::find(request('id'));
// Create output
$data = ...
echo json_encode($data);
}
}
If I were you, I would use a RESTful API with route model binding, specifically the explicit binding.
RouteServiceProvider.php
public function boot()
{
parent::boot();
Route::model('employee', App\Employee::class);
}
Route
Route::get('api/employees/{employee}', 'EmployeeController#get');
Controller
public function get(Employee $employee)
{
// The id being valid is already done by forcing it to be an Employee
// It is also an ajax call because it is going to the api route
// This will json_encode the employee object.
return $employee;
}
I'm trying to setup a simple POST method with AJAX, posting to a Laravel controller and processed.
The issue I am having is returning a response that the AJAX call understand and can use.
routes.php
Route::controller('supply-us/application', 'ApplicationController');
Route::post('supply-us/application', 'ApplicationController#processSupplierApplication');
AJAX stuff to get form data:
$('#supplierChainCheckForm').submit(function( event ) {
event.preventDefault();
function csrfSafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
// As we're using the "csfrUnsafeMethod" of POST - we'll need to setup the csfr token to be passed between client and server:
$.ajaxSetup({
// This is standard before send method for the ajaxSetup() function:
beforeSend: function(xhr, settings) {
// If settings.type in $.ajax method is unsafe i.e., if it is 'POST' then we'll need to set X-CSRFToken in the xhr Request Header: omitted && sameOrigin(settings.url) currently;
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", $('meta[name="csrf-token"]').attr('content'));
}
}
});
// Get all the form inputs into an array:
var $inputs = $('#supplierChainCheckForm :input');
// We can now loop over all of the input names & values of the form:
var values = {};
$inputs.each(function() {
values[this.name] = $(this).val();
});
$.ajax({
type: 'POST', //This will always be a post method for the supplier chain check form.
url: 'supply-us/application', //URL endpoint for the post form method: we'll set this to the controller function we're targeting.
data: { 'companyName': values['companyName'] ,'_token': '{{ csrf_token() }}'}
}).done(function(response) {
console.log(response.companyName);
});
});
ApplicationController.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response;
class ApplicationController extends FrontController {
public function getSupplierApplication() {
return self::getPage('supply-us/application');
}
public function processSupplierApplication() {
if (!Input::get('companyName') == null) {
$company = Input::get('companyName');
return Response::json([ 'companyName' => $company ], 200);
} else {
$company = "No compnay specified";
return Response::json([ 'companyName' => $company ], 200);
}
}
}
However, combining all of the above gives me
console.log(response.companyName) as "undefined"
Please advise. Please note, I am using Laravel 4.1.*
Update function parameter as below;
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Input;
class ApplicationController extends FrontController {
public function getSupplierApplication() {
return self::getPage('supply-us/application');
}
public function processSupplierApplication(Request $request) {
if (!$request->input('companyName') == null) {
$company = $request->input('companyName');
return Response::json([ 'companyName' => $company ], 200);
} else {
$company = "No compnay specified";
return Response::json([ 'companyName' => $company ], 200);
}
}
}
I want to retrieve the id of the user that's currently online. But I CANNOT do it with the following code:
Route::middleware('auth:api')->post('/optionelections', function (Request $request) {
return $request->user();
});
The reason is that I keep getting the same unauthorised error from Laravel. I've been trying to fix this error for days and I can't seem to find a solution. So I'm trying to do it in a different way but I don't know how. I'm currently using Passport to store my token and my client_id in local storage.
this is my apply_election.vue
import {apiDomain} from '../../config'
export default {
name: 'applyForElection',
data () {
return {
election: {},
newOption: {'election_id': ''},
//this is where the user_id should come
newOption: {'user_id': ''}
}
},
methods: {
createOption: function () {
var itemId = this.$route.params.id
this.newOption.election_id = itemId
this.$http.post(apiDomain + 'optionelections', this.newOption)
.then((response) => {
this.newOption = {'election_id': itemId}
alert('you applied!')
this.$router.push('/electionsnotstarted')
}).catch(e => {
console.log(e)
alert('there was an error')
this.$router.push('/electionsnotstarted')
})
}
},
created: function () {
var itemId = this.$route.params.id
this.$http.get('http://www.nmdad2-05-elector.local/api/v1/elections/' + itemId)
.then(function (response) {
this.election = response.data
})
}
}
And this in my OptionElectionsController.php
public function store(Request $request)
{
$optionElection = new OptionElection();
$optionElection->user_id = $request['user_id'];
$optionElection->option = "something";
$optionElection->votes = 0;
$optionElection->election_id = $request['election_id'];
$optionElection->accepted = 0;
if ($optionElection->save()) {
return response()
->json($optionElection);
}
}
This is my Auth.js
export default function (Vue) {
Vue.auth = {
setToken (token, expiration) {
localStorage.setItem('token', token)
localStorage.setItem('expiration', expiration)
},
getToken () {
var token = localStorage.getItem('token')
var expiration = localStorage.getItem('expiration')
if (!token || !expiration) {
return null
}
if (Date.now() > parseInt(expiration)) {
this.destroyToken()
return null
} else {
return token
}
},
destroyToken () {
localStorage.removeItem('token')
localStorage.removeItem('expiration')
},
isAuthenticated () {
if (this.getToken()) {
return true
} else {
return false
}
}
}
Object.defineProperties(Vue.prototype, {
$auth: {
get: () => {
return Vue.auth
}
}
})
}
You are using the TokenGuard of Laravel, There many way to let the guard recognise the authentication, the best methods:
Send the token in api_token attribute in the request's query.
this.newOption.api_token = token;
Send the token in Authorization header with Bearer prefix.
{
headers: {
Authorization: 'Bearer THE_TOKEN'
}
}