I have been trying to find a way to determine Ajax calls in Laravel but I have not found any documentation about it.
I have an index() controller function where I want to handle the response differently based on the nature of the request. Basically this is a resource controller method that is bound to GET request.
public function index()
{
if(!$this->isLogin())
return Redirect::to('login');
if(isAjax()) // This is what I am needing.
{
return $JSON;
}
$data = array(
'records' => $this->table->fetchAll()
);
$this->setLayout(compact('data'));
}
I know the other methods of determining the Ajax request in PHP but I want something specific to Laravel.
Thanks
Updated:
I tried using
if(Request::ajax())
{
echo 'Ajax';
}
But I am receiving this error:
Non-static method Illuminate\Http\Request::ajax() should not be called statically, assuming $this from incompatible context
The class shows that this is not a static method.
Maybe this helps. You have to refer the #param
/**
* Display a listing of the resource.
*
* #param Illuminate\Http\Request $request
* #return Response
*/
public function index(Request $request)
{
if($request->ajax()){
return "AJAX";
}
return "HTTP";
}
$request->wantsJson()
You can try $request->wantsJson() if $request->ajax() does not work
$request->ajax() works if your JavaScript library sets an X-Requested-With HTTP header.
By default Laravel set this header in js/bootstrap.js
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
In my case, I used a different frontend code and I had to put this header manually for $request->ajax() to work.
But $request->wantsJson() will check the axios query without the need for a header X-Requested-With:
// Determine if the current request is asking for JSON. This checks Content-Type equals application/json.
$request->wantsJson()
// or
\Request::wantsJson() // not \Illuminate\Http\Request
To check an ajax request you can use if (Request::ajax())
Note:
If you are using laravel 5, then in the controller replace
use Illuminate\Http\Request;
with
use Request;
I hope it'll work.
You are using the wrong Request class. If you want to use the Facade like: Request::ajax() you have to import this class:
use Illuminate\Support\Facades\Request;
And not Illumiante\Http\Request
Another solution would be injecting an instance of the real request class:
public function index(Request $request){
if($request->ajax()){
return "AJAX";
}
(Now here you have to import Illuminate\Http\Request)
if(Request::ajax())
Looks to be the right answer.
http://laravel.com/api/5.0/Illuminate/Http/Request.html#method_ajax
For those working with AngularJS front-end, it does not use the Ajax header laravel is expecting. (Read more)
Use Request::wantsJson() for AngularJS:
if(Request::wantsJson()) {
// Client wants JSON returned
}
Those who prefer to use laravel helpers they can check if a request is ajax using laravel request() helper.
if(request()->ajax())
// code
public function index()
{
if(!$this->isLogin())
return Redirect::to('login');
if(Request::ajax()) // This is check ajax request
{
return $JSON;
}
$data = array();
$data['records'] = $this->table->fetchAll();
$this->setLayout(compact('data'));
}
Sometimes Request::ajax() doesn't work, then use \Request::ajax()
Do something like this
public function functionName(User $user): string
{
(string) $message = "";
// check if request is ajax
if(request()->ajax())
{
if($this->isOwner($user->id)){
$message = 'success';
}else{
$message = "You are unauthorized to perform this action.";
}
}else{
$message = 'Wrong server request';
}
return $message;
}
after writing the jquery code perform this validation in your route or in controller.
$.ajax({
url: "/id/edit",
data:
name:name,
method:'get',
success:function(data){
console.log(data);}
});
Route::get('/', function(){
if(Request::ajax()){
return 'it's ajax request';}
});
Most of the answers are working fine. We can also check the request header
request()->header('Accept')=='application/json'
to check the request type
Related
I am implementing Flutterwave implementation as found on Medium but I am getting the error:
The GET method is not supported for this route. Supported methods: POST.
http://localhost:8000/rave/callback?resp=%7B%22name%22%3A%22opop%22%2C%22data%22%3A%7B%22data%22%3A%7B%22responsecode%22%3A%2200%22%2C%22responsetoken%22%3Anull%2C%22responsemessage%22%3A%22successful%22%7D%2C%22tx%22%3A%7B%22id%22%3A2424493%2C%22txRef%22%3A%22rave_611fc5fe12df9%22%2C%22orderRef%22%3A%22URF_1629472286526_3670035%22%2C%22flwRef%22%3A%22FLW-MOCK-44b7ecdb3a2183c971db03d669dc1554%22%2C%22redirectUrl%22%3A%22http%3A%2F%2Flocalhost%3A8000%2Frave%2Fcallback%22%2C%22device_fingerprint%22%3A%22888b449800a5003eaf1eeea02d5d52db%22%2C%22settlement_token%22%3_
I am implementing Post routes as shown in:
Route::post('/pay', 'RaveController#initialize')->name('pay');
Route::post('/rave/callback', 'RaveController#callback')->name('callback');
And on my controller, I've got:
public function initialize() {
//This initializes payment and redirects to the payment gateway
//The initialize method takes the parameter of the redirect URL
Rave::initialize(route('callback'));
}
/**
* Obtain Rave callback information
* #return void
*/
public function callback() {
$data = Rave::verifyTransaction(request()->txref);
dd($data); // view the data response
if ($data->status == 'success') {
//do something to your database
} else {
//return invalid payment
}
}
Please can anyone help me solve this problem? Especially since changing the route to get returns null. Thanks a whole lot!
that's because of you are calling the route again here that is mean you will go to this direction with get method
public function initialize(){
Rave::initialize(route('callback'));
}
the best solution to you you have to call this function without routing it as following
public function initialize(Request $request){
//here now you will not routing with get you will call the function inside it
Rave::initialize($this->callback($request->all()));
}
/**
* Obtain Rave callback information
* #return void
*/public function callback($request){
$data = Rave::verifyTransaction($request->txref);
dd($data); // view the data response
if ($data->status == 'success') {
//do something to your database
}
else {
//return invalid payment
}
}
I suppose Route::post('/rave/callback', 'RaveController#callback')->name('callback'); Is your problem. It should be Route::get
Hi. I am sorry for editing this directly as I cant find the reply button. Route::get() returns null for this particular implementation.
I need some help on a topic that is making me crazy on Laravel 5.2
I have the following routes.php, which I have reduced to the minimum :
use Illuminate\Http\Request;
/**
* Category Page
*/
Route::get('/category/test/', function()
{
dd("I'm in !");
dd(Input::all());
$page = Input::get('page');
if(isset($page)){
dd($page);
}
}
When I call the following url : http://192.168.99.100/category/test?page=55, I would expect to get the parameter page in Input or Request but however it is always empty. The following code just displays "I'm in !" but nothing else.
Can you help me understanding what is wrong in here ? I previously used controllers and Request parameters but it was also empty, thus this simple test. Note that post requests are working fine.
Thanks !
I finally found it out !
That was a problem in my nginx configuration, that prevented php variable QUERY_STRING to be correctly set up and Laravel is basing on this variable to retrieve the data.
For more information, see https://serverfault.com/questions/231578/nginx-php-fpm-where-are-my-get-params/362924#362924
Thaks for your answers anyway !
You can use both , actually there is no error in your code except if you missed the use statement for Input facade.
use Illuminate\Http\Request;
/**
* Category Page
*/
Route::get('/category/test/', function()
{
dd(Input::all());
dd("I'm in !");
$page = Input::get('page');
if(isset($page)){
dd($page);
}
}
So question is why you are getting nothing! because the route is GET request so if you post/update/patch anything to it you will get methodNotAllowed exception. Now just goto your browser and type http://whateverdomain/category/test/?page=atiq&have=fun and yes now there is something.........
Route::get('/category/test/', function(Request $request)
{
$input=$request->All();
dd($input);
$page = request->get('page');
if(isset($page)){
dd($page, request->get('have'));
}
}
because you didn't told function to expect request
it shall be
Route::get('/category/test/', function(Request $Request)
{
$input=$Request->All();
dd($input);
// usage $input['query'];
$page = Input::get('page');
if(isset($page)){
dd($page);
}
}
I want to redirect from a controller and pass data;
public function fortest(Request $request)
{
$user = DB::table('user2s')->where('name', $request->name)->first();
if (isset($user))
{
return redirect('/fortest2', ['user'=>$user]);//compact('user'));
//return $this->fortest2($request);
}
}
public function fortest2(Request $request)
{
return $request->name;
}
Route::get('/fortest', 'UserController#fortest');
Route::get('/fortest2/', 'UserController#fortest2');
The code works when calling the controller directly from within the controller. The data type has a model. How can I accomplish this?
If you want to pass data in a redirect, you can use the with() method.
You have to append it to the redirect like so:
redirect('/fortest2')->with('data', 'value');
It will be saved in your current session, so it will be only persistent until you refresh the page again. If you want to store it for longer you have to go with a database/textfile etc. You can then check for it using
if (session()->has('data')) { // check if it exists
$value = session('data'); // to retrieve value
}
You can also send errors with the redirect (from validation i.e.) using withErrors(), sending the current input with it using withInput()
For what you want to achieve, try using this in your controller. This will just send the users name with the redirect:
$user = DB::table('user2s')->where('name', $request->name)->first();
redirect('/fortest2')->with('username', $user->name);
You can then access is via session('username')
You need to use sessions to pass data when using redirect:
return redirect('/fortest2')->with('data', 'some data');
Then get data from session:
$data = session('data');
Or you can persist data in DB and then get it from there.
Try to do like this
public function fortest(Request $request)
{
$user = DB::table('user2s')->where('name', $request->name)->first();
if(isset($user))
{
return redirect('/fortest2/$user->name');
}
}
public function fortest2($name)
{
return $name;
}
Your route
Route::get('/fortest', 'UserController#fortest');
Route::get('/fortest2/{$name}', 'UserController#fortest2');
I have a controller which has a redirect function:
public function myControllerMethod()
{
$data = $this->blabla();
return Redirect::to('previousroute')->with('data', $data);
}
This previousroute is handled by otherControllerMethod() like so:
public function otherControllerMethod()
{
$data = Session::get('data');
return $this->makeView($data);
}
Unfortunately, Laravel forgets this session data. I've done this many times before and I have never seen if forget the session flash data after a single redirect. What is going on here? I have tried both adding and removing "web" middleware but nothing works. If anyone knows why this happens let me know.
use Session;
public function myControllerMethod()
{
$data = $this->blabla();
Session::set('data', $data);
return Redirect::to('previousroute')->with('data', $data);
}
public function otherControllerMethod()
{
$data = Session::get('data');
return $this->makeView($data);
}
Try like this. Use the session and set the data in session and get it from where you want.
I have had the same Issue before. Basically I needed to call send function when redirecting using Redirect facade. So you need to change your myControllerMethod to:
public function myControllerMethod()
{
$data = $this->blabla();
return Redirect::to('previousroute')->with('data', $data)->send();
}
As send() function of class Symfony\Component\HttpFoundation\Response calls the function sendContent() which sends the data when redirecting.
Hope this helps.
In myControllerMethod you are passing the data obj/var as a Request.
In otherControllerMethod you are requesting the Session data which is not set.
In order to put data to the session you should do:
Session::put('data','value')
and then it will be available with:
Session::get('data');
if ($this->getRequest()->isXmlHttpRequest()) {
$this->_helper->layout->disableLayout();
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('view', 'html');
$ajaxContext->initContext();
}
how does this actually work... my ajax get page is local.maker/profile/check
i got ajax to work fine but i dont know what to edit from the above...
$ajaxContext->addActionContext('???', 'html');
ps.. i am requesting a json
I use the following code to use AJAX context helper.
In your controller create a preDispatch method to set up your contexts like this:
public function preDispatch()
{
$this->_helper->ajaxContext()
->addActionContext('index', array('json', 'html'))
->addActionContext('anotheraction', 'json')
->initContext();
}
And then in you action methods use:
public function indexAction()
{
if ($this->_helper->ajaxContext()->getCurrentContext() == 'json') {
// ajax code here
} else {
// non ajax code here
}
}
Also in your ajax request you must use the variable format to set the current context, for example
http://www.mydomain.com/index/format/json
to request a json response.
Note: The context switcher automatically disables the layout and view, any view variable set in the controller will automatically be encoded into a json string and sent.
I hope this helps
Kind regards
Garry
Please go through the example . It has everything what you are looking for .
http://framework.zend.com/manual/en/zend.controller.actionhelpers.html#zend.controller.actionhelpers.contextswitch.ajaxcontext
addActionContext( <action>, <format>);
Can request comment/process/format/json or via query variable . See the example .