Search code examples
laravellaravel-8laravel-blade

how can I achieve loop indexing in recursive laravel components?


I am stuck in a problem and tried so many things but all invain. actually what i want is to achieve incrementive indexing in recursive laravel components. like for example i want the indexing to be 0, 1, 2, 3, 4, 5, 6, 7, 8 ...... so on.

my code is,

@foreach($costs as $cost)
   <x-estimation-item :cost="$cost" />
@endforeach

and my component is,

@props([
    'cost',
])

<div>
    @foreach($cost->children as $child)
        <x-estimation-item :cost="$child" />
    @endforeach
</div>

I am using Laravel Adjacency List package and my levels are upto 9 levels. Now I just want to increment value each time the components calls. i will access that incremented value above the foreach loop of childrens. Any idea how I can achieve this ?

Any Idea or piece of code if possible!


Solution

  • Have your EstimationItem component accept a counter prop.

    App\View\Components\EstimationItem

    <?php
    
    namespace App\View\Components;
    
    use Illuminate\View\Component;
    
    class EstimationItem extends Component
    {
        public $cost;
        public $counter;
    
        public function __construct($cost, $counter) {
            $this->cost = $cost;
            $this->counter = $counter;
            $counter->increment();
        }
    }
    

    resources/views/components/estimation-item.blade.php

    @props([
        'cost',
        'counter'
    ])
    
    <div>
        @foreach($cost->children as $child)
            {{ $counter->getValue() }}
            <x-estimation-item :cost="$child" :counter="$counter" />
        @endforeach
    </div>
    

    Declare a Counter class to container the index and increment it each time a component is rendered.

    App\Pojos\Counter

    namespace App\Pojos;
    
    final class Counter {
        private int index;
    
        public function __construct() {
            $this->index = 0;
        }
    
        public function increment() {
            $this->index++;
        }
    
        public function getValue(): int {
            return $this->index;
        }
    }
    

    Initialize the counter and pass it down as prop to your component.

    @php
    $counter = new \App\Pojo\Counter();
    @endphp
    
    @foreach($costs as $cost)
       {{ $counter->getValue() }}
       <x-estimation-item :cost="$cost" :counter="$counter" />
    @endforeach
    

    You can see this in action here in the playground.