Strange results with Carbon filter on Eloquent collection in blade template

php laravel eloquent blade php-carbon

111 просмотра

2 ответа

52 Репутация автора

I have a weird issue that I can't see any obvious solution to.

I am building a jQuery graph of transaction totals for the last 30 days but I am not getting the proper output. Here is the relevant blade template code:

@for ($i = 29; $i >= 1; $i--)
{y: '{{ \Carbon\Carbon::now()->subDays($i)->toDateString() }}', item1: '{{ $transactions->whereDate('created_at', '=', \Carbon\Carbon::now()->subDays($i)->toDateString())->where('status', 'C')->sum('amount') }}'},  
@endfor
{y: '{{ \Carbon\Carbon::now()->toDateString() }}', item1: '{{ $transactions->where('created_at', '>=', \Carbon\Carbon::now()->toDateString())->where('status', 'C')->sum('amount') }}'}

With my dummy data, when $i=3 it should return '10.00' and everything else should return '0'.

Couple notes: If I make the FIRST output as '3 days ago', it returns the expected value. Example:

{y: '{{ \Carbon\Carbon::now()->subDays(3)->toDateString() }}', item1: '{{ $transactions->whereDate('created_at', '=', \Carbon\Carbon::now()->subDays(3)->toDateString())->where('status', 'C')->sum('amount') }}'},
@for ($i = 29; $i >= 1; $i--)
{y: '{{ \Carbon\Carbon::now()->subDays($i)->toDateString() }}', item1: '{{ $transactions->whereDate('created_at', '=', \Carbon\Carbon::now()->subDays($i)->toDateString())->where('status', 'C')->sum('amount') }}'},  
@endfor
{y: '{{ \Carbon\Carbon::now()->toDateString() }}', item1: '{{ $transactions->where('created_at', '>=', \Carbon\Carbon::now()->toDateString())->where('status', 'C')->sum('amount') }}'}

Also, if I hard code any values into the graph it works fine so that should rule out any jQuery issue. So in essence it seems that only the first time I use this call it works.

I'm assuming the solution is to clean up the amount of Carbon/collection calls (since there is like 60 total), but I'm not quite sure where to start on that. I am passing a collection from my controller as 'transactions'.

Result:

{y: '2016-06-18', item1: '0'},
...
{y: '2016-07-15', item1: '0'},
{y: '2016-07-16', item1: '0'},
{y: '2016-07-17', item1: '0'},
{y: '2016-07-18', item1: '0'}

Expected result:

{y: '2016-06-18', item1: '0'},
...
{y: '2016-07-15', item1: '10.00'},
{y: '2016-07-16', item1: '0'},
{y: '2016-07-17', item1: '0'},
{y: '2016-07-18', item1: '0'}
Автор: Stephen Fox Источник Размещён: 18.07.2016 09:47

Ответы (2)


0 плюса

2329 Репутация автора

try doing

with(clone $transaction)->query_here

your query might be overwritten/changed through out the loop.

Hope it helped!

Автор: Wreigh Размещён: 19.07.2016 12:52

0 плюса

1454 Репутация автора

I'm guessing you have some logic error. Anyway, you shouldn't build the graph data in your view. Instead place the logic in your controller, or better yet in a presenter or service class. However for now, placing it in your controller will be just fine.

Try this, in your controller, add:

$graph = [];
$currentDay = \Carbon\Carbon::now();

for ($i=0; $i < 30; $i++) {
    if ($i > 0) {
        // Subtract a day starting from the second loop
        $currentDay->subDay();
    }

    $dateString = $currentDay->toDateString();

    $currentDayData = [
        'y' => $dateString,
        'item1' => $transactions->whereDate('created_at', $dateString)->where('status', 'C')->sum('amount'),
    ];

    // Prepend to final array
    array_unshift($graph, $currentDayData);
}

$graph = json_encode($graph);

// Don't forget to export $graph to your view

Then in your view place the JSON string in the appropriate data-* attribute. For example:

<div id="graph" data-graph="{{ $graph }}"></div>

Finally in your .js file you can grab the data and build the graph from there:

// Note: You don't need to parse the JSON string manually
// since jquery will do that automatically in this case
const data = $('#graph').data('graph');

// Then feed the data into whatever graph API that you use

I haven't tested this code, so let me know how it goes.

Автор: Fahmi Размещён: 26.06.2017 05:38
32x32