Laravel 5 return JSON or View depends on if ajax or not

I would like to know if there is a magic method to use this script:

If I call the page through an AJAX request, the controller returns a JSON object, otherwise it returns a view, I try to do this on all my controllers without changing each method.

For example, I know I can do this:

if (Request::ajax()) 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 main behavior, rather than spend time changing them. any idea?

+6
source share
3 answers

The easiest way is to create a method that will be used by all 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 (\Request::ajax()) { return json_encode($objects); } return view($template, $objects); } } 

And this is one of the controllers expanding it:

 <?php namespace App\Http\Controllers; class MyController extends Controller { public function index() { $object = new Object1; $object2 = new Object2; return $this->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->ajax()) { return response()->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->makeResponse($request, $template, compact($object, $object2)); } } 
+4
source

There is no magic, but you can easily override ViewService in 3 steps:

1.Create your factory view ( 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 (\Request::ajax()) { return $data; } return parent::make($view, $data, $mergeData); } } 

2.Create a 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() { parent::register(); } /** * Overwrite original so we can register MyViewFactory * * @return void */ public function registerFactory() { $this->app->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->setContainer($app); $env->share('app', $app); return $env; }); } } 

3.in your_project_path/config/app.php : change 'Illuminate\View\ViewServiceProvider', to 'App\Providers\MyViewProvider',

What does it do:

it tells your application to use a different view provider that will register your view factory $env = new MyViewFactory($resolver, $finder, $app['events']); on line 33 of MyViewProvider.php , which will check if the request is AJAX and return if true, or continue with the original behavior return parent::make($view, $data, $mergeData); in line MyViewFactory.php 19

Hope this helps you

+1
source

In laravel 5.1, this is the best way:

 if (\Illuminate\Support\Facades\Request::ajax()) return response()->json(compact($object1, $object2)); else return view('template', compact($object, $object2)); 
0
source

Source: https://habr.com/ru/post/985960/


All Articles