Title: Laravel 5 return JSON or View depends if ajax or not
Tags: php;laravel;controller;laravel-5
Question: I would like to know if there is a magic method to use this scenario :
If I call a page via an AJAX request the controller returns a JSON object, otherwise it returns a view, i'm trying to do this on all my controllers without changin each method.
for example i know that i can do this :
if (Request75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0jax()) return compact($object1, $object2);
else return view('template', compact($object, $object2));
but I have a lot of controllers/methods, and I prefer to change the basic behavior instead of spending my time to change all of them. any Idea ?
Comment: IMHO , what you are trying to achieve is not possible without touching the controller methods. I would suggest you use @fungku 's method and adjust your methods that need this. At least you have a single place then  to change the response behaviour of your controllers again.


Here is another answer: There is no magic but you can easily override ViewService in 3 steps:
1.create your view factory (your_project_path/app/MyViewFactory.php)
<?php
* Created by PhpStorm.
* User: panos
* Date: 5/2/15
* Time: 1:35 AM
namespace App;
use Illuminate\View\Factory;
class MyViewFactory extends Factory {
public function make($view, $data = array(), $mergeData = array())
if (\Request75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0jax()) {
return $data;
}
return parent75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0make($view, $data, $mergeData);
2.create your view service provider (your_project_path/app/providers/MyViewProvider.php)
<?php namespace App\Providers;
use App\MyViewFactory;
use Illuminate\View\ViewServiceProvider;
class MyViewProvider extends ViewServiceProvider {
/**
* Register the application services.
*
* @return void
*/
public function register()
parent75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0register();
/**
* Overwrite original so we can register MyViewFactory
*
* @return void
*/
public function registerFactory()
$this-&gt;app-&gt;singleton('view', function($app)
{
// Next we need to grab the engine resolver instance that will be used by the
// environment. The resolver will be used by an environment to get each of
// the various engine implementations such as plain PHP or Blade engine.
$resolver = $app['view.engine.resolver'];
$finder = $app['view.finder'];
// IMPORTANT in next line you should use your ViewFactory
$env = new MyViewFactory($resolver, $finder, $app['events']);
// We will also set the container instance on this view environment since the
// view composers may be classes registered in the container, which allows
// for great testable, flexible composers for the application developer.
$env-&gt;setContainer($app);
$env-&gt;share('app', $app);
return $env;
});
3.in your_project_path/config/app.php:
change 'Illuminate\View\ViewServiceProvider',
to 'App\Providers\MyViewProvider',
What this do:
it tells your application to use another view provider which will register your view factory
$env = new MyViewFactory($resolver, $finder, $app['events']);
in line 33 of MyViewProvider.php which will check if request is AJAX and return if true or continue with original behavior
return parent75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0make($view, $data, $mergeData);
in MyViewFactory.php line 19
Hope this help you,
Comment for this answer: NOTE: this will not work with `view('template')->with('key','data');` data since the returned data is not a View.
It would have to return an implementation of the `\Illuminate\Contracts\View\View` interface.

Here is another answer: In laravel 5.1, this is the best way:
if (\Illuminate\Support\Facades\Request75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0jax())
return response()-&gt;json(compact($object1, $object2));
return view('template', compact($object, $object2));

Here is another answer: The easiest way would be to make a method that is shared between all of your controllers.
Example:
This is your controller class that all other controllers extend:
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
abstract class Controller extends BaseController
protected function makeResponse($template, $objects = [])
if (\Request75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0jax()) {
return json_encode($objects);
}
return view($template, $objects);
And this is one of the controllers extending it:
<?php namespace App\Http\Controllers;
class MyController extends Controller
public function index()
$object = new Object1;
$object2 = new Object2;
return $this-&gt;makeResponse($template, compact($object, $object2));
Update for Laravel 5+
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
protected function makeResponse($request, $template, $data = [])
if ($request-&gt;ajax()) {
return response()-&gt;json($data);
}
return view($template, $data);
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class MyController extends Controller
public function index(Request $request)
$object = new Object1;
$object2 = new Object2;
return $this-&gt;makeResponse($request, $template, compact($object, $object2));
Comment for this answer: @RuChernChong you can. or you can use either `\Request75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0jax()`, `\Request75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0xpectsJson()`, or `\Request75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0wantsJson()` depending on exactly what you want.
Comment for this answer: Instead of `if (\Request75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0jax())`, can I use `if (\Request75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0isJson())`? Thank you!

Here is another answer: The solution suggested by @ryanwinchester is really good. I, however, wanted to use it for the responses from update() and delete(), and there naturally return view() at the end doesn't make a lot of sense as you mostly want to use return redirect()-&gt;route('whatever.your.route.is'). I thus came up with that idea:
// App\Controller.php
/**
* Checks whether request is ajax or not and returns accordingly
* @param  array $data
* @return mixed
*/
protected function forAjax($data = [])
if (request()-&gt;ajax()) {
return response()-&gt;json($data);
}
return false;
// any other controller, e.g. PostController.php
public function destroy(Post $post)
// all stuff that you need until delete, e.g. permission check
$comment-&gt;delete();
$r = ['success' =&gt; 'Wohoo! You deleted that post!']; // if necessary
// checks whether AJAX response is required and if not returns a redirect
return $this-&gt;forAjax($r) ?: redirect()-&gt;route('...')-&gt;with($r);

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 4, 'CommentCount': 1, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2015:00:04/25/15', 'FavoriteCount': 1.0, 'PostTypeId': 1, 'Tags': '<php><laravel><controller><laravel-5>', 'Title': 'Laravel 5 return JSON or View depends if ajax or not', 'ViewCount': 9225, 'id': 29868903, 'user_AboutMe': '', 'user_AccountId': 3894010.0, 'user_DisplayName': 'zeomega', 'user_Reputation': 345.0, 'user_Views': 49.0, 'user_id': 3223525.0}}