Home > Enterprise >  How can I overwrite a variable in the parent controller from a child controller in this Laravel appl
How can I overwrite a variable in the parent controller from a child controller in this Laravel appl

Time:03-11

I am working on a Laravel 8 app with users and posts.

I have a PostsController and a FeaturedPostsController.

I want to use the logic of the PostsController inside the FeaturedPostsController and only add to the child controller what is spaciffic to it. For this purpose, I have:

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;

class PostsController extends Controller {
    public function index(Request $request){
        $viewData = $this->loadViewData();
        $viewData['page_title'] = "Posts";
        $viewData['posts'] = $this->posts($request);
        return view('posts', $viewData);
    }
}


namespace App\Http\Controllers;
use App\Http\Controllers\PostsController;
use Illuminate\Http\Request;

class FeaturedPostsController extends PostsController {
    public function __construct(Request $request) {
        parent::index($request);
    }
    
    public function index(Request $request){
        $viewData['page_title'] = "Featured posts";
    }
}

In the rotes file:

Route::get('/posts', [PostsController::class, 'index'])->name('posts');
Route::get('/featured-posts', [FeaturedPostsController::class, 'index']);

In the posts view I have:

<h1 >{{ $page_title }}</h1>

The goal

The goal is to have "Featured posts" as page title page with on the /featured-posts route.

In other words, I want $viewData['page_title'] = "Posts" to be overwritten by $viewData['page_title'] = "Featured posts".

The problem

On the Featured posts page, I can't see the posts view at all, unless I comment out the index method of the FeaturedPostsController.

Where is my mistake?

CodePudding user response:

1- You do not necessarily need two controllers. Since you have two routes, you can just point those to two different methods in the PostController. Also, you should not need to override the index method since featured posts would have a different logic, but if it does, you can move the repeating logic into another method. But, you most certainly do not need to have a constructor in the FeaturedController class and do not need to call parent's index class.

Suggested approach 1:

class PostsController extends Controller {
 public function index(Request $request){
     $viewData = $this->viewData($request, "Posts");
     return view('posts', $viewData);
 }
 public function featuredPosts(Request $request){
     $viewData = $this->viewData($request, "Featured Posts");
     return view('posts', $viewData);
 }

 private function viewData($request, $pageTitle){
    $viewData = $this->loadViewData(); //maybe you can use this existing function?
    $viewData['page_title'] = $pageTitle;
    $viewData['posts'] = $this->posts($request);
    return $viewData;
 }
}

//in route
Route::get('/posts', [PostsController::class, 'index'])->name('posts');
Route::get('/featured-posts', [PostsController::class, 'featuredPosts']);

2- If you must have two controllers, you could assign the title to a class variable in the PostController. So, suggestion 2:

class PostsController extends Controller {
 public $title = "Posts";
 public function index(Request $request){
    $viewData = $this->loadViewData();
    $viewData['page_title'] = $this->title;
    $viewData['posts'] = $this->posts($request);
    return view('posts', $viewData);
 }
}
class FeaturedPostsController extends PostsController {

 public function __construct(){
   $this->title = "Featured Posts";
 }
}

And since PostsController has an index method, you do not need to redeclare if no logic changes.

  • Related