Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

joenyambura's avatar

Handling Grouped and Ordered Transactions in Laravel with Livewire Compatibility

Hello Laravel Community,

I am currently facing a challenge in a Laravel project using Livewire. My goal is to fetch a user's transactions, group them by date, and order them in descending order. While I can achieve this directly in a Laravel controller, I encounter issues when implementing the same logic in a Livewire component:

         BadMethodCallException
        Method Illuminate\Database\Eloquent\Collection::getMorphClass does not exist.

Here's a brief overview of my current approach in the controller:

 public function index()
{
    // Get the authenticated user
    $user = Auth::user();
    // Use the authenticated user's id
    $userId = $user->id;

    $companiesCount = Cache::remember("user_companies_count_{$userId}", now()->addMinutes(30), function () use ($user) {
        return $user->companies()->count();
    });

    if ($companiesCount === 0) {
        session()->flash('firstTime', true);
        return redirect()->route('company.create');
    }

    // Get transactions associated with the user from the last 30 days, in descending order
    $transactions = Cache::remember("user_transactions_30_days_{$userId}", now()->addHours(12), function () use ($user) {
        return $user->transactions()
            ->where('transaction_date_time', '>=', Carbon::now()->subDays(30))
            ->orderBy('transaction_date_time', 'desc')
            ->get();
    });
    // Group the transactions by date
    // Assuming $transactions is already retrieved from the cache
    $groupedTransactions = Cache::remember("grouped_transactions_{$userId}", now()->addHours(12), function () use ($transactions) {
        return $transactions->groupBy(function ($transaction) {
            return $transaction->transaction_date_time->format('Y-m-d');
        });
    });

    $dailyBalances = Cache::remember("user_daily_balances_{$userId}", now()->addHours(24), function () use ($userId, $groupedTransactions) {
        return PeriodicBalance::where('user_id', $userId)
            ->where('period_type', 'daily')
            ->whereIn('period_start_date', $groupedTransactions->keys())
            ->get()
            ->keyBy('period_start_date');
    });
    return view('dashboard.index', [
        'groupedTransactions' => $groupedTransactions,
        'dailyBalances' => $dailyBalances
    ]);
}

And here is the Livewire component briefly:

        class GroupedTransactions extends Component

{ public $groupedTransactions; public $userId; public $days; public $dailyBalances; protected $listeners = ['transactionAdded' => '$refresh'];

public function mount()
{

    // Get the authenticated user
    $user = Auth::user();
    // Use the authenticated user's id
    $userId = $user->id;
    // Get transactions associated with the user from the last 30 days, in descending order
    $transactions = Cache::remember("user_transactions_30_days_{$userId}", now()->addHours(12), function () use ($user) {
        return $user->transactions()
            ->where('transaction_date_time', '>=', Carbon::now()->subDays(30))
            ->orderBy('transaction_date_time', 'desc')
            ->get();
    });
    // Group the transactions by date
    // Assuming $transactions is already retrieved from the cache
    $groupedTransactions = Cache::remember("grouped_transactions_{$userId}", now()->addHours(12), function () use ($transactions) {
        return $transactions->groupBy(function ($transaction) {
            return $transaction->transaction_date_time->format('Y-m-d');
        });
    });
    $this->groupedTransactions = $groupedTransactions;
    $this->dailyBalances = Cache::remember("user_daily_balances_{$userId}", now()->addHours(24), function () use ($userId, $groupedTransactions) {
        return PeriodicBalance::where('user_id', $userId)
            ->where('period_type', 'daily')
            ->whereIn('period_start_date', $groupedTransactions->keys())
            ->get()
            ->keyBy('period_start_date');
    });
}

#[On('transactionAdded')]
public function render()
{
    return view('livewire.grouped-transactions',
        [
            'groupedTransactions' => $this->groupedTransactions,
            'dailyBalances' => $this->dailyBalances
        ]);
}

}

I will later modify the component to follow best practices when I get the solution for my problem.

I would greatly appreciate any advice, tips, or insights from the community on how to best tackle this issue.

Thank you in advance for your help!

0 likes
0 replies

Please or to participate in this conversation.