Rendering blade components via AJAX doesn't initiate component attributes and methods - laravel

I have a Blade Component class like this:
class RolesSelect extends Component
{
public $roles;
public $user;
public function __construct($roles = null, $user = null)
{
//... some logic goes here (irrelevant)
}
public function isSelected($user,$role)
{
// ... some logic
}
public function render()
{
return view('components.roles-select');
}
}
When I render my component as usual <x-roles-select></x-roles-select> everything goest fine.
But here starts the problem: when I load the component via AJAX, I use the view('components.roles-select')->render(). And the component can't see the isSelected method anymore.
It throws this error: Undefined variable: isSelected
I tried to research the Blade and Component classes, but only came this far:
$roleSelect = new RolesSelect($roles, $user);
$roleSelect->resolveView()->render();
I can access everything, but the isSelected method.

I was close enough. Dabbled a bit with the code, and got it working!
In my controller (or just the route method), you have to initialise the component class, and pass it's data to the view like this:
$roleSelect = new RolesSelect($roles, $user);
if (request()->wantsJson()) {
return response()->json([
'content' => $roleSelect->resolveView()->with($roleSelect->data())->render()
],200);
}

Related

Laravel - Passing a variable from controller to model or accessing a variable in the controller from the model

I want to pass a variable in the controller to the model in laravel.
In Controller,
$withoutUser = True;
$post->update([
'status' => 'inactive'
]);
In model,
protected static function boot(): void
{
parent::boot();
static::updated(fn (Model $model) =>
// Need to access the $withoutUser variable from here?
);
}
Is there a method to pass the $withoutUser variable when calling $post->update() or is it possible to access the $withoutUser variable in the controller when the static::updated method is called in model?
Thanks
You can do this by creating a property on the post model. The exact same instance of the post class is sent to the event dispatcher. So you can write your code something like this:
class Post extends Model
{
public bool $updateWithoutUser = false;
...
}
And then in your controller:
$post->updateWithoutUser = true;
$post->update([
'status' => 'inactive',
]);
And in the boot function:
protected static function boot(): void
{
parent::boot();
static::updated(function (Post $post) {
if ($post->updateWithoutUser) {
...
}
});
}
Though you should be careful if you are queueing the listener, because in that case the property will not be preserved as it fetches the post from the database when the listener is run from the queue.

How to pass a parameter to a laravel controller from redirect within the same controller

How do I pass a true false value to the controller from the redirect in the class and to the router and back to another function in the same controller class if that makes sense
Like
public function 1() {
return redirect('route2');
}
public function2() {
I need to access the variable here that some how gets passed from the first function
}
Because these functions are both on my main controller and I need to pass a variable through the route
and back into the controller or is there a way to put a state variable on the class or something I just need to call a function on the controller with conditions from the previous controller function that called called the redirect route.
Also sorry if I am mixing up class and function I am new to laravel and MVC in general.
You can do something like this:
public function first() {
return redirect()->action(
[YourController::class, 'second'], ['value' => true]
);
}
public function second($value = null) {
// whatever you want
}
https://laravel.com/docs/9.x/redirects#redirecting-controller-actions
I think this code help you:
public function 1() {
return to_route('YOUR_ROUTE_NAME', ['value' => 'some things...']);
}
public function2(Request $request, $value) {
// Use the value passed as a route parameter
// $value is 'some things...'
}

Unusual Livewire Behaviour: object become empty array

I have a component where I display the list of transactions and show details of each transaction using a modal.
class TableTranscation extends Component
{
use WithPagination, Alert, AuthorizesRequests;
...
public $transaction;
public $detailModal = false;
public function showDetail($id)
{
$this->transaction = Transaction::find($id);
$this->detailModal = true;
//dd transaction variable here return correct result
//dd($this->transaction);
}
public function render()
{
return view("livewire.user.transaction.transaction-table", [
"transactions" => current_user()->transactions()->paginate($this->perPage)
]);
}
}
Whenever I call to showDetail method from the component, the transaction remains Array[0] in Livewire devtool.
I tried adding the mount method but the Livewire devtool also showed Array[0].
public function mount()
{
$this->transaction = Transaction::find(1);
}
When I {{ dd($transaction) }} from the view it return correct transaction.
Any solution to this problem or bug from the tool?

Laravel collection display and short issue

Hello guys!
I have a a little problem with collections. I have never worked with these. I would like to display a collection at my welcome blade but there is a problem. My collection is not in the contrroller, the collection's place is in the App/Repositories/xyz.php and in a function. How can i pass this function to the controller and after show it at the welcome blade??
App/repositories/xyz.php
public function getcars(): Collection
{
return collect([
new Car(...)
)];
controller
public function __invoke(): View
{
return view('welcome', ['cars' => collect([
new Car() ------> I would like to put datas from xyz.php repo here
new Car()
new Car()
....
And welcome.blade file where i would like to display
<div class="car-list">
<h2>{{ $title }}</h2>
#foreach($cars as $car)
<x-car :car="$car" />
#endforeach
</div>
You could do that in many ways:
Creating new instance
use App\repositories\Xyz;
public function __invoke(): View
{
$repo = new Xyz();
return view('welcome')->with('cars', $repo->getcars());
}
Pulling your class from the container
use App\repositories\Xyz;
public function __invoke(): View
{
$repo = app(Xyz::class);
return view('welcome')->with('cars', $repo->getcars());
}
Using dependency injection to resolve it from container
use App\repositories\Xyz;
protected Xyz $repo;
public function construct(Xyz $xyz): View
{
$this->repo = $xyz;
}
public function __invoke(): View
{
return view('welcome')->with('cars', $this->repo->getcars());
}
I believe from your Controller file, you can create an object property of your Repository via __construct() method like this:
protected MyRepository $myRepository;
public function __construct(MyRepository $myRepository)
{
$this->myRepository = $myRepository;
}
Then, you can call $this->myRepository's method from there, for example like getting records, etc. Then you can pass the result to your view.

Laravel, Singleton - how to send data to all controllers?

I'm doing shopping site. I made Cart Model, which is Singleton. My shopping cart exists in session always ( no matter or User is login or not ). Now I have to invoke every time in every Controllers and actions getInstance to check or there's key "cart".
Is there a possibility to do this automaticly for all views?
Here is code of my Singleton:
class Cart
{
private $cartModel;
private static $instance;
private function __construct()
{
$this->cartModel = new CartModel();
$cart = Session::get('cart');
if ($cart == null) {
Session::put('cart', array());
}
}
private function __clone()
{
}
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new Cart();
}
return self::$instance;
}
public function get(){
return Session::get('cart');
}
}
And here for example how it looks in Controllers and actions:
class StoreController extends Controller
{
public function mainSite()
{
$cart=Cart::getInstance()->get();
return View('zoo');
}
public function showCategory($categoryName)
{
$cart=Cart::getInstance()->get();
$category = new Category();
$categoryId = (int)$category->getCategoryId($categoryName);
$subCategories = Subcategory::where('category_id', $categoryId)->get();
return View('zoo-category', ['subCategories' => $subCategories, 'categoryName' => $categoryName]);
}
public function showSubcategory()
{
$cart=Cart::getInstance()->get();
}
I have to do this all the time: $cart=Cart::getInstance()->get();
Is there a possibility to do this only one time?
You can take advantage of Laravel's dependency injection. Bind your class to the IoC container and you can either access it through the IoC container or you can have Laravel automatically inject this into your controllers in several different ways.
Read more here: https://laravel.com/docs/5.4/container
Add it to base controller's constructor so that it gets called on every controller method.
// app/Http/Controllers/Controller.php
protected $cart;
public function __construct()
{
$this-> cart = Cart::getInstance()->get();
}
But i honestly see no point in your singleton class. All it does is set the cart with an empty array when it's not defined. Also $this->cartModel = new CartModel(); is this ever used?

Resources