4
\$\begingroup\$

I'm quite new to Laravel, and I'm not sure what am I doing is the best practice.

I'd like to return JSON if the request is Ajax, or return a view otherwise. This is the way I made it, and it works fine, but I'm not sure if this is the best way(it seems long winded). I'd really like to hear your suggestions.

public function store()
{
 $input = Input::all();
 if(!$this->settings->fill($input)->isValid())
 {
 if ( Request::ajax() ){
 return $this->jsonFailure(array(
 'errors' => $this->settings->errors
 ));
 }
 else{
 return Redirect::route('admin.settings.create')
 ->withInput()
 ->withErrors($this->settings->errors);
 }
 }
 $this->settings->save();
 if ( Request::ajax() )
 return $this->jsonSuccess('success');
 else
 Redirect::route('admin.settings.index');
}
Alex L
5,7832 gold badges26 silver badges69 bronze badges
asked Jul 24, 2014 at 4:54
\$\endgroup\$
0

3 Answers 3

5
\$\begingroup\$

The only problem with this approach is that as you add more methods, you are going to end up with an awful lot of repeated if (Request::ajax()) ... blocks all over your code.

Here's what I do for my sites:

<?php
class ApiController extends Controller {
 protected function makeResponse($data, $isError = false, $redirectToIfNotAjax = '/') {
 if (Request::ajax()) {
 if ($isError) {
 return $this->jsonFailure(array(
 'errors' => $data
 ));
 } else {
 return $this->jsonSuccess($data);
 }
 } else {
 if ($isError) {
 return Redirect::route($redirectToIfNotAjax)
 ->withInput()
 ->withErrors($data);
 } else {
 Redirect::route($redirectToIfNotAjax);
 }
 }
 }
}

(This is not exactly the same as what I am using, but it's pretty close.)

Then, inherit your controllers from ApiController instead of just Controller.

Here is what your example would look like:

public function store()
{
 $input = Input::all();
 if(!$this->settings->fill($input)->isValid())
 {
 return makeResponse($this->settings->errors, true, 'admin.settings.create')
 }
 $this->settings->save();
 return makeResponse('success', false, 'admin.settings.index')
}

Much cleaner!

answered Jul 24, 2014 at 5:02
\$\endgroup\$
0
4
\$\begingroup\$

If you follow Single Responsibility principle than your controller should not know how view is presented. I would rather create view presenter class in you app/Projectname/Presenters folder and than inject it thru constructor. That way your code would be cleaner and more testable.

answered Jul 24, 2014 at 6:30
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Great, this is somewhat I had in mind. To put it in a dedicated class and use it everywhere you need \$\endgroup\$ Commented Jul 24, 2014 at 7:44
1
\$\begingroup\$

make two different methods and in the routes.php change one for get and another for post and do the ajax request with post, that way you can use the same URL and separate functionality.

answered Jul 24, 2014 at 4:32
\$\endgroup\$
1
  • 1
    \$\begingroup\$ That sounds like significant unnecessary code duplication. \$\endgroup\$ Commented Jul 24, 2014 at 4:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.