Pass variable from one controller to another laravel 5.4 - laravel

I am trying to pass the request variable from a form request to another controller (the second controller is going to have a lot of code in it so I want to use it to keep the main controller clean), but when I try and pass the variable over, nothing happens, the variable data isn't sent over.
Here is my current code:
class mainController extends Controller{
public function store(Request $request)
{
//validation
$otherClass = (new secondController)->createDBEntry($request);
}
}
class secondController extends Controller{
public function createDBEntry($request)
{
return $request;
}
}
However, nothing is passed from the $request into the secondController. If I echo something in the secondController it works no problem, so I know it's being called, but the data isn't being sent over. What am I missing here? Keep in mind I am fairly new to laravel and I am using 5.4.

Your code works just fine. You are just expecting a behavior that is never going to happen though because:
new secondController instantiates secondController
createDBEntry($request) calls the method createDBEntry passed
with $request
The returned value is stored in the variable $otherClass
And that's it! nothing more is (and will be) happening. If you want to see the value of $otherClass (and see your code working) you have to return it:
class mainController extends Controller
{
public function store(Request $request)
{
$otherClass = new secondController
$otherClass->createDBEntry($request);
return $otherClass;
}
}
class secondController extends Controller
{
public function createDBEntry($arg)
{
return $arg;
}
}

Related

Parent Controller class to call child overridden methods (Laravel)

I know this might seem anti pattern, and a lot will throw stones at me, but please hear me out.
I want to create a generic Controller to support many reference tables (mostly id, label). So I did something like this:
class GenericController extends Controller
{
public function index($modelName)
{
$x = '\\App\\Models\\'.$modelName;
$data = $model->all();
return view('generic.list', ['model'=>$model, 'data'=>$data]);
}
}
And this way my routes in web.php will be reduced to the minimum like this:
//List
Route::get('/{model}', function ($model) {
return App::call('\App\Http\Controllers\GenericController#index', ['modelName' => $model]);
});
It's working very well with simple CRUD actions like store, update, etc.. However I know I am over simplifying the design because sometimes I need to return a field from a joined table in the index list for example. That's where I am heading into a dead end, sort of.
My first thought was to create a controller for each model that inherits from the GenericController like this:
class CategoryController extends GenericController
{
}
And whenever I need to override the GenericController method, I would simply add it to the child class. However how can I do this from inside the GenericController (call a method in a sub class from parent class)? Because otherwise I will have to create routes for every single model which is against my wish.
So basically I am looking for something like this:
class GenericController extends Controller
{
public function index($modelName)
{
$x = '\\App\\Models\\'.$modelName;
//this thing I'm looking for is something like this:
//Check if we have CategoryController and it has a definition for index
//if yes do something like $data = CategoryController->index();
//otherwise just call $data = $model->all();
return view('generic.list', ['model'=>$model, 'data'=>$data]);
}
}
So I know this seems weird and anti-pattern, but other wise how can I create my generic routes and controller actions?
You are right, this is not really what is called "best practice". However, from a POO standpoint, it is an interesting question.
This what you can do:
class GenericController extends Controller
{
protected function getData(string $model)
{
return $model::all();
}
public function index($modelName)
{
$model = '\\App\\Models\\'.$modelName;
$data = $this->getData($model);
return view('generic.list', ['model'=>$model, 'data'=>$data]);
}
}
By default, the data will be retrieved "the simple way", using $data = $this->getData($model);.
However, if you make a CategoryController:
class CategoryController extends GenericController
{
protected function getData(string $model)
{
return Category::query()->with('something')->where('hello','world')->get();
}
}
You will just have to override the getData method inside your CategoryController.
This is the way to go if you want something clean. Of course, your categories routes will have to use this CategoryController instead of the GenericController.

Laravel Model Controller Dependency injection

I have the following problem. I hope my approach is not completely wrong, feel free to advice.
I have a Model class Chat.php
protected $skip;
protected $take;
protected $agreements;
protected $chat;
public function getSkip()
{
return $this->skip;
}
public function setSkip($skip)
{
$this->skip = $skip;
}
public function getTake()
{
return $this->take;
}
public function setTake($take)
{
$this->take = $take;
}
public function __construct(array $attributes = array())
{
parent::__construct($attributes);
$this->setTake(8);
$this->setSkip(8);
}
I set properties skip and take here.
Then, I have the DashboardController
class DashboardController extends Controller
{
private $chat;
/**
* DashboardController constructor.
* #param $chat
*/
public function __construct(Chat $chat)
{
$this->chat = $chat;
}
/**
* Display a listing of the authenticated resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$chats = Chat::orderBy('created_at','desc')->skip($this->chat->getSkip())->take($this->chat->getTake())->get();
$agreements = AgrType::orderBy('created_at','desc')->take(10)->get();
return view('sections.dashboard', compact('chats','agreements'));
}
public function loadMore()
{
$this->chat->setSkip($this->chat->getSkip() - 1 );
$this->chat->setTake($this->chat->getTake() - 1);
return redirect('/dashboard');
}
My approach is as follows:
After a user clicks on button, route /loadmore get him to this controller and triggers loadMore function.
LoadMore function then gets values through accessors and sets values with mutator.
Index method then simply reads this values.
So the meaning is: I show chat window (rather maybe comments window cause this si not really a chat), index method is called.
Index method reads the values and displays comments according to query. -> this one is OK
Now, what does NOT work:
When I click button, loadMore function gets called, sets the values which index method then reads and reloads according to them.
What did I try: I tried loadMore method to display its own values (changed) and return them, but then I have a new route for reloaded chat and it is not what I want.
What do I miss? Is my approach OK? (I know javascript is maybe better for this, but I want a Laravel way, get and post.)
Thanks in advance.
Your controller functions get executed within in completely separate requests.
All return redirect('/dashboard'); does in loadMore() send your browser to the dashboard route. Your browser then makes a new request to index() on which your controller gets instantiated again, its __construct() function run again and a new empty Chat model gets instantiated.
I recommend you put the take and skip parameters into your url like this:
$router->get('/dashboard/{skip}/{take}', 'DashboardController#index');
And change your index() function to this:
public function index($skip, $take)
That way it will work, however the even better way of doing it would be to use Laravel's paginate() function: https://laravel.com/docs/5.6/pagination
public function index()
{
$chats = Chat::orderBy('created_at','desc')->paginate();
$agreements = AgrType::orderBy('created_at','desc')->take(10)->get();
return view('sections.dashboard', compact('chats','agreements'));
}

Pass variable from one method to another in same controller Laravel

I need to pass select option value from store method to show
i need to pass the $typeg value to show method
public function store(Request $request ) {
$typeg = $request->input('type');
}
public function show($id) {
dd($this->store($typeg));
}
i get
Undefined variable:
or
Too few arguments to function app\Http\Controllers\appController::show(), 1 passed and exactly 2 expected
Try this
on the first function you have some variable witch you want to pass it to another function\method
Than you need to use $this and the name of the other method you'd like to pass the var too something like this.
public function oneFunction(){
$variable = "this is pretty basic stuff in any language";
$this->anotherFunction($variable)
}
public function anotherFunction($variable){
dd($variable);
}
Store your data on session (or somewhere else like cookie, cache, database). So you can reach the data later.
class SomeController extends Controller {
public function store(Request $request ) {
session(["typeg"=>$request->input('type')])
}
public function show($id) {
dd(session("typeg"));
}

How to call BaseController public function from child classes in Laravel (4)?

I have a CustomController. For not to repeat myself, I defined getVars function in BaseController. I want to call getVars function from some functions in CustomController.
However, Laravel returns 404 error without any exception. What is wrong?
class BaseController extends Controller {
public function getVars($var1, $var2, $var3=Null, $var4=Null) {
return [];
}
}
class CustomController extends BaseController {
public function doBla1($var1, $var2) {
$vars = $this->getVars();
}
public function doBla2() {
$vars = $this->getVars();
}
public function doBla3() {
$vars = $this->getVars();
}
}
Sorry :( I found the reason of error. The names of doBla1 and getVars functions are same. This results in a 404 error. Sorry :(
$this is useful when you have method/function defined in same controller.
For functions inside parent controller you can use
Parent::getVars($var1, $var2)

Code in IndexController::indexAction executes before each request

Is it a bug or a feature?
I have two controllers IndexController and TestController.
The first one looks like this:
class IndexController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
$products = $this->basket->get('products', []);
$products[] = uniqid('index.index');
$this->basket->set('products', $products);
}
public function testAction()
{
var_dump($this->basket->products);
}
}
I just save an array in a session with indexAction and show that data in testAction.
For the first request output for index/test is an empty array. But the second and all following requests add one new element. If I comment line $this->basket->set('products', $products); then the next request to index/test will add another value to array but after that extra pushing to array does not happen.
Then I add
class TestController extends \Phalcon\Mvc\Controller
{
public function indexAction()
{
$products = $this->basket->get('products', []);
$products[] = uniqid('test.index');
$this->basket->set('products', $products);
die();
}
public function testAction()
{
var_dump($this->basket->products);
die();
}
}
But for request test/test I again get changing in session variable.
Looks like that route index/index always executes before any other routes. Is it a feature, bug or some sort of misconfiguration? I use standard configuration for multimodule application from official documentation.
This is more than likely because your browser is hitting /favicon.ico in the background. I've been stung by this a number of times across different frameworks.
Try putting a favicon.ico file (or a rule to block that path) and see if the problem persists.

Resources