Unusual Livewire Behaviour: object become empty array - laravel

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?

Related

Livewire Event not firing - Modals

I'm trying to create a separate component to open a modal, but my events are not getting fired.
My parent component is Admin, and the component to open a modal is AddVideo
here is my Admin Component
public function add()
{
$this->emit('addvideoModal');
}
This is the button to fire that method
<x-jet-button wire:click="add">
{{ __('+ Video') }}
</x-jet-button>
This is from the AddVideoModal
class AddVideo extends Component
{
protected $listeners = ['addvideoModal' => 'render'];
public function render()
{
return view('livewire.add-video');
}
}
*Note, all my components are enclosed in a single Element. Am I missing something here?
Any help would be greatly appreciated.
apparently need to create a new method.
protected $listeners = ['addvideoModal' => 'sample'];
public function sample()
{
$this->addModal = true;
}

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.

How to auto populate Laravel Nova Action Fields with their respective values from database?

This is the code I have inside my Action Class:
public function fields()
{
return [
Date::make('checkin_date'),
Date::make('checkout_date'),
Textarea::make('remark'),
Text::make('holder_name'),
Text::make('holder_surname'),
Text::make('clientReference'),
];
}
What I'm looking for is to show the actual database value on each field. So a user would either choose to edit or keep values as they are.
You can access the request object on the action definition and use a constructor to pass the value to the action.
class MyDemoAction extends Action
{
use InteractsWithQueue, Queueable;
public function __construct(MyDemoModel $model) {
$this->model = $model;
}
public function handle(ActionFields $fields, Collection $models)
{
//
}
public function fields()
{
return [
Date::make('checkin_date')->default(function() {
$this->model->my_value;
}),
Date::make('checkout_date'),
Textarea::make('remark'),
Text::make('holder_name'),
Text::make('holder_surname'),
Text::make('clientReference'),
];
}
To make sure that you can always pass a valid MyModel object, you can limit your action to only be visible on resourceDetail.
Registering A

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

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);
}

Laravel Ardent is not updating

I'm trying to submit updates to items in the Items model. However, Ardent never actually performs the updates when the update method receives them but doesn't throw an error:
public function update($id)
{
$item = Item::findOrFail($id);
if ($item->save()) {
return Redirect::back()->with('message', "Item #$id updated!");
} else {
return Redirect::back()->withInput()->withErrors($item->errors());
}
}
What is wrong with my controller logic here?
It looks like you need to set those variables
class Item extends \LaravelBook\Ardent\Ardent {
// hydrates on new entries' validation
public $autoHydrateEntityFromInput = true;
// hydrates whenever validation is called
public $forceEntityHydrationFromInput = true;
}
properly to get the behavior you expect.
Source: https://github.com/laravelbook/ardent#automatically-hydrate-ardent-entities

Resources