Adgower

Member Since 7 Months Ago

Oklahoma City

Experience Points
23,750
Total
Experience

1,250 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
215
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

  • Community Pillar

    Earned once your experience points ranks in the top 10 of all Laracasts users.

Level 5
23,750 XP
Dec
15
1 month ago
Activity icon

Awarded Best Reply on Livewire FilePond Clear After Upload

It's working now: I think it was a caching issue?

<div>
    <button wire:click="upload" class="btn btn-primary">Upload</button>
    {{-- <input wire:model="newDocument" type="file"> --}}
    @error('newDocument')
    {{ $message }}
    @enderror
    <div wire:ignore x-data x-init="

        FilePond.setOptions({
            server: {
                process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
                    @this.upload('newDocument', file, load, error, progress)
                },
                revert: (filename, load) => {
                    @this.removeUpload('newDocument', filename, load)
                },
            },
        });
        var Pond = FilePond.create($refs.input);
        this.addEventListener('pondReset', e => {
            Pond.removeFiles();
        });


    ">

        <input wire:model="newDocument" type="file" x-ref="input">
    </div>

    <ul class="list-group">
        @foreach ($event->documents as $document)
        <li class="list-group-item d-flex justify-content-between align-items-center">
            <a wire:click.prevent="$emitTo('admin.courses.show-document', 'selectedDocument', '{{ $document->id }}')"
                href="#" target="_blank"><i class='far fa-file-pdf'></i>{{ $document->name }}</a>

            {{-- <span class="badge bg-primary rounded-pill">14</span> --}}
        </li>
        @endforeach
    </ul>
</div>

Activity icon

Replied to Livewire FilePond Clear After Upload

It's working now: I think it was a caching issue?

<div>
    <button wire:click="upload" class="btn btn-primary">Upload</button>
    {{-- <input wire:model="newDocument" type="file"> --}}
    @error('newDocument')
    {{ $message }}
    @enderror
    <div wire:ignore x-data x-init="

        FilePond.setOptions({
            server: {
                process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
                    @this.upload('newDocument', file, load, error, progress)
                },
                revert: (filename, load) => {
                    @this.removeUpload('newDocument', filename, load)
                },
            },
        });
        var Pond = FilePond.create($refs.input);
        this.addEventListener('pondReset', e => {
            Pond.removeFiles();
        });


    ">

        <input wire:model="newDocument" type="file" x-ref="input">
    </div>

    <ul class="list-group">
        @foreach ($event->documents as $document)
        <li class="list-group-item d-flex justify-content-between align-items-center">
            <a wire:click.prevent="$emitTo('admin.courses.show-document', 'selectedDocument', '{{ $document->id }}')"
                href="#" target="_blank"><i class='far fa-file-pdf'></i>{{ $document->name }}</a>

            {{-- <span class="badge bg-primary rounded-pill">14</span> --}}
        </li>
        @endforeach
    </ul>
</div>

Activity icon

Started a new Conversation Livewire FilePond Clear After Upload

I have the following which uploads a file fine:

<div>
    <button wire:click="upload" class="btn btn-primary">Upload</button>
    <input wire:model="newDocument" type="file">
    @error('newDocument')
    {{ $message }}
    @enderror
    <div wire:ignore x-data x-init="

        FilePond.setOptions({
            server: {
                process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
                    @this.upload('newDocument', file, load, error, progress)
                },
                revert: (filename, load) => {
                    @this.removeUpload('newDocument', filename, load)
                },
            },
        });
this.addEventListener('pondReset', e => {
            FilePond.removeFile();
        });

    ">

        <input wire:model="newDocument" type="file" class="filepond">
    </div>

    <ul class="list-group">
        @foreach ($event->documents as $document)
        <li class="list-group-item d-flex justify-content-between align-items-center">
            <a wire:click.prevent="$emitTo('admin.courses.show-document', 'selectedDocument', '{{ $document->id }}')"
                href="#" target="_blank"><i class='far fa-file-pdf'></i>{{ $document->name }}</a>

            {{-- <span class="badge bg-primary rounded-pill">14</span> --}}
        </li>
        @endforeach
    </ul>
</div>

but it doesn't clear the input after upload. I assume it is because wire:ignore?

in my upload method I set $this->newDocument = NULL. I assume I need to somehow use alpine/js to do the same concept? Is this the right direction?

Thanks

UPDATE:

I found this link: https://forum.laravel-livewire.com/t/how-to-reset-filepond-input-file/1595

But when I run

FilePond.removeFile();

It says FilePond.removeFile is not a function...

https://pqina.nl/filepond/docs/patterns/api/filepond-instance/#removing-files

any tips?

UPDATE:

I found this https://forum.laravel-livewire.com/t/clear-out-filepone-files/2449/2

He says I need to set it equal to an instance of FilePond

when I do that I get same problem:

var pond = FilePond.create($refs.input);

still says .removeFiles is not a function

Activity icon

Replied to File URL

I change to what you said and I deleted the sym link and re ran php artisan storage:link on the vm in the root directory of the project and now it is working. Thank you.

Dec
14
1 month ago
Activity icon

Started a new Conversation File URL

I am able to successfully upload a file to:

storage/app/public/documents/events/FILENAME.pdf

when I try to access it doesn't show in browser:

public function getUrl()
    {
        return Storage::disk('Event')->url($this->file_name);
    }

filesystems.php:

'Event' => [
            'driver' => 'local',
            'root' => storage_path('app/public/documents/events'),
            'url' => env('APP_URL').'/documents/events',
            'visibility' => 'public',
        ],

'links' => [
        public_path('storage') => storage_path('app/public'),
    ],

url generated:

https://laravel.local/documents/events/FILENAME.pdf

I ran storage:link and I see the file being uploaded, but the url its generating is wrong when I try to create a url for the file.

I'm using Homestead on windows 10, and I think I may have not done it right?

Any tips?

Thanks

Dec
09
1 month ago
Activity icon

Started a new Conversation WithCount Morph Through?

I have the following setup: Products has many items/variations, items has many inventories, and an inventory belongs to a morph (stockable which is a warehouse or a store), and the stockable (warehouse or store) belongs to 1 a region.

Maybe I am making this complicated, but I am trying to see how many regions a product is in and return for example: "Coding Product 1 is in 5 regions", so it returns the count of regions for each product.

I have setup a has Many through (Inventory::class, Item::class) on the Product to get the inventories for example $product->inventories. This is the part where I am stuck. If I $product->inventories->first()->stockable->region->id, gives me the region->id. This seems inefficient, and I was hoping I could deploy a has one through, but the inventory contains the stockable morphto relationship...

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;

    public function items()
    {
        return $this->hasMany(Item::class);
    }

    public function inventories()
    {
        return $this->hasManyThrough(Inventory::class, Item::class);
    }
}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Item extends Model
{
    use HasFactory;

    public function inventories()
    {
        return $this->hasMany(Inventory::class);
    }

    public function product()
    {
        return $this->belongsTo(Product::class);
    }
}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Lukeraymonddowning\Mula\Facades\Mula;

class Inventory extends Model
{
    use HasFactory;

    public function stockable()
    {
        return $this->morphTo();
    }

    public function item()
    {
        return $this->belongsTo(Item::class);
    }

    public function getValueAttribute()
    {
        return $this->quantity * $this->item->price;
    }

    public function getFormattedValueAttribute()
    {
        return Mula::parse($this->value, 'USD')->display();
    }
}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Lukeraymonddowning\Mula\Facades\Mula;

class Store extends Model
{
    use HasFactory;

    public function region()
    {
        return $this->belongsTo(Region::class);
    }

    public function itemInventory()
    {
        return $this->morphMany(Inventory::class, 'stockable');
    }

    public function getInventoryValueAttribute()
    {
        $total = 0;

        foreach($this->itemInventory as $inventory) {
            $total += $inventory->value;
        }

        return $total;
    }

    public function getFormattedInventoryValueAttribute()
    {
        return Mula::parse($this->inventory_value, 'USD')->display();
    }
}

Here is the query i'm currently building:

$products = Product::when($this->searchProducts != '', function($query) {
            $query->where('title', 'like', '%'.$this->searchProducts.'%');
        })->withCount(['items', 'inventories as store_count' => function($query) {
            $query->where('stockable_type', 'App\Models\Store');
        }, 'inventories as warehouse_count' => function($query) {
            $query->where('stockable_type', 'App\Models\Warehouse');
        }])->withAvg('items', 'price')->withAvg(['inventories as store_avg_quantity' => function($query) {
            $query->where('stockable_type', 'App\Models\Store');
        }, 'inventories as warehouse_avg_quantity' => function($query) {
            $query->where('stockable_type', 'App\Models\Warehouse');
        }], 'quantity')->withSum(['inventories as store_quantity' => function($query) {
            $query->where('stockable_type', 'App\Models\Store');
        }, 'inventories as warehouse_quantity' => function($query) {
            $query->where('stockable_type', 'App\Models\Warehouse');
        }, 'inventories as total_quantity'], 'quantity')->when($this->sortQuantity == true, function($query) {
            $query->orderBy('total_quantity', $this->sortDirection ? 'asc' : 'desc' );
        })->get();

I want to add withCount and get regions_count

any tips?

Activity icon

Replied to How To Simplify This Validation?

thanks ill check it out.

Dec
08
1 month ago
Activity icon

Started a new Conversation Slow Queries From Custom Accessors

I have a problem that I have created custom accessors to pull some data I need, but it is really slow and basically generates about 500 more queries than I just just query the model and use with on the relationships. Could someone point me in the right direction? Do I need to convert to sql query instead of using all the methods?

I'm using laravel debugbar to get this information

controller: using with saves about 10 queries

$regions = Region::when($this->searchRegions != '', function($query) {
            $query->where('title', 'like', '%'.$this->searchRegions.'%');
        })->with('stores')->with('warehouse')->get();

view

<div class="row">
        @foreach ($regions->sortByDesc('inventory_value') as $region)
        <div class="col-xs col-md-6 col-lg-4 col-xxl-3 mt-4">
            <div class="card">
                <div class="card-body">
                    <h5 class="card-title">{{ $region->title }}</h5>
                    <p class="card-text">
                        <a href="#">
                            {{ $region->warehouse->title }}
                        </a>
                    </p>
                    <p class="card-text">Stores: {{ count($region->stores) }}</p>
                    <p class="card-text">Unique Inventory Items: {{ count($region->itemInventory) }}</p>
                    <p class="card-text">Region Inventory Value: {{ $region->formatted_inventory_value }}</p>
                    <a href="#" class="btn btn-primary">View</a>
                </div>
            </div>
        </div>
        @endforeach
    </div>

model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Lukeraymonddowning\Mula\Facades\Mula;

class Region extends Model
{
    use HasFactory;

    public function stores()
    {
        return $this->hasMany(Store::class);
    }

    public function warehouse()
    {
        return $this->belongsTo(Warehouse::class);
    }

    public function getInventoryValueAttribute()
    {
        $total = 0;

        foreach($this->stores as $store) {
            $total += $store->inventory_value;
        }

        $total += $this->warehouse->inventory_value;

        return $total;
    }

    public function getFormattedInventoryValueAttribute()
    {
        return Mula::parse($this->inventory_value, 'USD')->display();
    }

    public function getItemInventoryAttribute()
    {
        $itemIds = collect();

        foreach($this->stores as $store) {
            $itemIds = $itemIds->merge($store->itemInventory->pluck('item_id'));
        }

        $itemIds = $itemIds->merge($this->warehouse->itemInventory->pluck('item_id'));

        $items = Item::find($itemIds->unique());

        return $items;
    }
}

Basically I'm dipping into multiple accessors a few models deep, and piling up the queries. Any tips would be great! Thanks.

Activity icon

Started a new Conversation How To Simplify This Validation?

This accomplishes what I need, but if someone could point me in the right direction with a way to simplify that would be great!

// https://laravel.com/docs/8.x/validation#conditionally-adding-rules
    $request->validate([
        'first_name'     => 'required',
        'last_name'      => 'required',
        'email'          => 'required_without_all:id_number,dob',
        'id_number'     => 'required_without_all:email,dob',
        'dob'            => 'required_without_all:email,id_number',
        'hours_per_week' => 'nullable|numeric',
        'hours_per_day'  => 'nullable|numeric',
        'supervisor'     => 'nullable|string',
        'start_date'     => 'date_format:Y-m-d'
    ]);

    if ($request->email != null && $request->id_number != null) {
        $request->validate([
            'email'      => 'email',
            'id_number' => 'digits:4'
        ]);
    }

    if ($request->email != null && $request->dob != null) {
        $request->validate([
            'email' => 'email',
            'dob'   => 'date_format:Y-m-d'
        ]);
    }

    if ($request->id_number != null && $request->dob != null) {
        $request->validate([
            'id_number' => 'digits:4',
            'dob'        => 'date_format:Y-m-d'
        ]);
    }

    if ($request->email != null) {
        $request->validate([
            'email' => 'email'
        ]);
    }

    if ($request->id_number != null) {
        $request->validate([
            'id_number' => 'digits:4'
        ]);
    }

    if ($request->dob != null) {
        $request->validate([
            'dob' => 'date_format:Y-m-d'
        ]);
    }
Dec
03
1 month ago
Activity icon

Awarded Best Reply on Nested Livewire Component Requires Double Click

I think the problem is this from the livewire docs:

Nested components CAN accept data parameters from their parents, HOWEVER they are not reactive like props from a Vue component.

So I moved my buttons up to the main component instead of the nested component. todos-list.blade.php:

<div class="row flex-column">
    @foreach ($todos as $todo)
    <div class="border shadow-sm rounded mx-3 mb-2 px-3 py-2 d-flex justify-content-between align-items-center">
        <livewire:todos.todo-show :todo="$todo" :key="$todo->id"/>
            <div>
                @if ($todo->completed)
                <button class="btn btn-outline-success" wire:click="toggleTodo({{ $todo->id }})">Completed!</button>
                @else
                <button class="btn btn-primary" wire:click="toggleTodo({{ $todo->id }})">Complete</button>
                @endif
                <button class="btn btn-outline-danger" wire:click="removeTodo({{ $todo->id }})">Delete</button>
            </div>
        </div>
        @endforeach

</div>

and then moved the methods from TodoShow -> TodosList

Solved it...

Another way to solve it: I added a property to store the value and used the mount function like this: TodoShow:

<?php

namespace App\Http\Livewire\Todos;

use App\Models\Todo;
use Livewire\Component;

class TodoShow extends Component
{
    public $todo;
    public $status;

    public function mount()
    {
        $this->status = $this->todo->completed;
    }

    public function render()
    {
        return view('livewire.todos.todo-show');
    }

    public function removeTodo(Todo $todo)
    {
        $todo->delete();

        $this->emitTo('todos.todos-list', 'render');
    }

    public function toggleTodo(Todo $todo)
    {
        $todo->toggle();

        $this->status = $todo->completed;

        $this->emitTo('todos.todos-list', 'render');
    }
}

Then in the view todo-show.blade.php I swapped the if statement to if($status)

Activity icon

Replied to Nested Livewire Component Requires Double Click

I think the problem is this from the livewire docs:

Nested components CAN accept data parameters from their parents, HOWEVER they are not reactive like props from a Vue component.

So I moved my buttons up to the main component instead of the nested component. todos-list.blade.php:

<div class="row flex-column">
    @foreach ($todos as $todo)
    <div class="border shadow-sm rounded mx-3 mb-2 px-3 py-2 d-flex justify-content-between align-items-center">
        <livewire:todos.todo-show :todo="$todo" :key="$todo->id"/>
            <div>
                @if ($todo->completed)
                <button class="btn btn-outline-success" wire:click="toggleTodo({{ $todo->id }})">Completed!</button>
                @else
                <button class="btn btn-primary" wire:click="toggleTodo({{ $todo->id }})">Complete</button>
                @endif
                <button class="btn btn-outline-danger" wire:click="removeTodo({{ $todo->id }})">Delete</button>
            </div>
        </div>
        @endforeach

</div>

and then moved the methods from TodoShow -> TodosList

Solved it...

Another way to solve it: I added a property to store the value and used the mount function like this: TodoShow:

<?php

namespace App\Http\Livewire\Todos;

use App\Models\Todo;
use Livewire\Component;

class TodoShow extends Component
{
    public $todo;
    public $status;

    public function mount()
    {
        $this->status = $this->todo->completed;
    }

    public function render()
    {
        return view('livewire.todos.todo-show');
    }

    public function removeTodo(Todo $todo)
    {
        $todo->delete();

        $this->emitTo('todos.todos-list', 'render');
    }

    public function toggleTodo(Todo $todo)
    {
        $todo->toggle();

        $this->status = $todo->completed;

        $this->emitTo('todos.todos-list', 'render');
    }
}

Then in the view todo-show.blade.php I swapped the if statement to if($status)

Activity icon

Replied to Nested Livewire Component Requires Double Click

If I don't use a nested component it works fine. For example todo-list has the foreach and buttons etc.

If I use the nested component like I am now that is where the problem is.

Activity icon

Replied to Nested Livewire Component Requires Double Click

database only shows 0 and 1 as value when changed. So it stays 0 and 1.

Activity icon

Replied to Nested Livewire Component Requires Double Click

I just noticed when I first click the button it does change the value in the database correctly, but it isn't until 2nd click that the button re-renders and shows the button correctly and updates the value in db. The 3rd click it correctly toggles value in database and button view correctly.

Activity icon

Replied to Nested Livewire Component Requires Double Click

the default value is 0/false in database

Here is the test of that method:

[email protected]:~/code/todo-livewire$ php artisan tinker
Psy Shell v0.10.4 (PHP 7.4.11 — cli) by Justin Hileman
>>> $todo = Todo::find(1);
[!] Aliasing 'Todo' to 'App\Models\Todo' for this Tinker session.
=> App\Models\Todo {#4225
     id: 1,
     title: "I was a large pool.",
     completed: 1,
     created_at: "2020-12-03 22:34:15",
     updated_at: "2020-12-03 22:36:38",
   }
>>> $todo->toggle();
=> null
>>> dump($todo);
App\Models\Todo^ {#4225
  #fillable: array:2 [
    0 => "title"
    1 => "completed"
  ]
  #connection: "mysql"
  #table: "todos"
  #primaryKey: "id"
  #keyType: "int"
  +incrementing: true
  #with: []
  #withCount: []
  #perPage: 15
  +exists: true
  +wasRecentlyCreated: false
  #attributes: array:5 [
    "id" => 1
    "title" => "I was a large pool."
    "completed" => false
    "created_at" => "2020-12-03 22:34:15"
    "updated_at" => "2020-12-03 22:37:17"
  ]
  #original: array:5 [
    "id" => 1
    "title" => "I was a large pool."
    "completed" => false
    "created_at" => "2020-12-03 22:34:15"
    "updated_at" => "2020-12-03 22:37:17"
  ]
  #changes: array:2 [
    "completed" => false
    "updated_at" => "2020-12-03 22:37:17"
  ]
  #casts: []
  #classCastCache: []
  #dates: []
  #dateFormat: null
  #appends: []
  #dispatchesEvents: []
  #observables: []
  #relations: []
  #touches: []
  +timestamps: true
  #hidden: []
  #visible: []
  #guarded: array:1 [
    0 => "*"
  ]
}
=> App\Models\Todo {#4225
     id: 1,
     title: "I was a large pool.",
     completed: false,
     created_at: "2020-12-03 22:34:15",
     updated_at: "2020-12-03 22:37:17",
   }
>>> $todo->toggle();
=> null
>>> dump($todo);
App\Models\Todo^ {#4225
  #fillable: array:2 [
    0 => "title"
    1 => "completed"
  ]
  #connection: "mysql"
  #table: "todos"
  #primaryKey: "id"
  #keyType: "int"
  +incrementing: true
  #with: []
  #withCount: []
  #perPage: 15
  +exists: true
  +wasRecentlyCreated: false
  #attributes: array:5 [
    "id" => 1
    "title" => "I was a large pool."
    "completed" => true
    "created_at" => "2020-12-03 22:34:15"
    "updated_at" => "2020-12-03 22:37:35"
  ]
  #original: array:5 [
    "id" => 1
    "title" => "I was a large pool."
    "completed" => true
    "created_at" => "2020-12-03 22:34:15"
    "updated_at" => "2020-12-03 22:37:35"
  ]
  #changes: array:2 [
    "completed" => true
    "updated_at" => "2020-12-03 22:37:35"
  ]
  #casts: []
  #classCastCache: []
  #dates: []
  #dateFormat: null
  #appends: []
  #dispatchesEvents: []
  #observables: []
  #relations: []
  #touches: []
  +timestamps: true
  #hidden: []
  #visible: []
  #guarded: array:1 [
    0 => "*"
  ]
}
=> App\Models\Todo {#4225
     id: 1,
     title: "I was a large pool.",
     completed: true,
     created_at: "2020-12-03 22:34:15",
     updated_at: "2020-12-03 22:37:35",
   }
>>> $todo->toggle();
=> null
>>> dump($todo);
App\Models\Todo^ {#4225
  #fillable: array:2 [
    0 => "title"
    1 => "completed"
  ]
  #connection: "mysql"
  #table: "todos"
  #primaryKey: "id"
  #keyType: "int"
  +incrementing: true
  #with: []
  #withCount: []
  #perPage: 15
  +exists: true
  +wasRecentlyCreated: false
  #attributes: array:5 [
    "id" => 1
    "title" => "I was a large pool."
    "completed" => false
    "created_at" => "2020-12-03 22:34:15"
    "updated_at" => "2020-12-03 22:37:40"
  ]
  #original: array:5 [
    "id" => 1
    "title" => "I was a large pool."
    "completed" => false
    "created_at" => "2020-12-03 22:34:15"
    "updated_at" => "2020-12-03 22:37:40"
  ]
  #changes: array:2 [
    "completed" => false
    "updated_at" => "2020-12-03 22:37:40"
  ]
  #casts: []
  #classCastCache: []
  #dates: []
  #dateFormat: null
  #appends: []
  #dispatchesEvents: []
  #observables: []
  #relations: []
  #touches: []
  +timestamps: true
  #hidden: []
  #visible: []
  #guarded: array:1 [
    0 => "*"
  ]
}
=> App\Models\Todo {#4225
     id: 1,
     title: "I was a large pool.",
     completed: false,
     created_at: "2020-12-03 22:34:15",
     updated_at: "2020-12-03 22:37:40",
   }
>>>
Activity icon

Started a new Conversation Nested Livewire Component Requires Double Click

I have a simple todo app:

The problem is when I click a button to toggle completed. The button requires you to click it twice. When I inspect I see that on the first click it adds to the element:

wire:initial-data="{"fingerprint":{"id":"3k5l2c0etHn1H0aVPRuT","name":"todos.todo-show","locale":"en"},"effects":{"listeners":[]},"serverMemo":{"children":[],"errors":[],"htmlHash":"528e0713","data":{"todo":[]},"dataMeta":{"models":{"todo":{"class":"App\Models\Todo","id":10,"relations":[],"connection":"mysql"}}},"checksum":"11a5f638221702a54589fabc2716b565ad6c51c08d2e4665cb6009556ad36840"}}"

Then on the second click it works fine and continues to work fine. The delete button works fine on first click.

If you can point me in the right direction that would help thanks!

Livewire components: TodoShow:

<?php

namespace App\Http\Livewire\Todos;

use App\Models\Todo;
use Livewire\Component;

class TodoShow extends Component
{
    public $todo;

    public function render()
    {
        return view('livewire.todos.todo-show');
    }

    public function removeTodo(Todo $todo)
    {
        $todo->delete();

        $this->emitTo('todos.todos-list', 'render');
    }

    public function toggleTodo(Todo $todo)
    {
        $todo->toggle();

        $this->emitTo('todos.todos-list', 'render');
    }
}

TodosList:

<?php

namespace App\Http\Livewire\Todos;

use App\Models\Todo;
use Livewire\Component;

class TodosList extends Component
{
    protected $listeners = ['render'];

    public function render()
    {
        $todos = Todo::latest()->get();

        return view('livewire.todos.todos-list', compact('todos'));
    }
}

Views: todos-list.blade.php

<div class="row flex-column">
    @foreach ($todos as $todo)
        <livewire:todos.todo-show :todo="$todo" :key="$todo->id"/>
    @endforeach
</div>

todo-show.blade.php:

<div class="border shadow-sm rounded mx-3 mb-2 px-3 py-2 d-flex justify-content-between align-items-center">
    <div>
        {{ $todo->title }}
    </div>
    <div>
        @if ($todo->completed)
        <button class="btn btn-outline-success" wire:click="toggleTodo({{ $todo->id }})">Completed!</button>
        @else
        <button class="btn btn-primary" wire:click="toggleTodo({{ $todo->id }})">Complete</button>
        @endif
        <button class="btn btn-outline-danger" wire:click="removeTodo({{ $todo->id }})">Delete</button>
    </div>
</div>

Todo.php model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Todo extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'completed'];

    public function toggle()
    {
        $this->update([
            'completed' => !$this->completed,
        ]);
    }
}
Activity icon

Awarded Best Reply on Livewire Nested Component Not Working

I solve it by changing the key used on the todo-show model:

:key="$loop->index" -> :key="$todo->id"
Activity icon

Replied to Livewire Nested Component Not Working

I solve it by changing the key used on the todo-show model:

:key="$loop->index" -> :key="$todo->id"
Activity icon

Replied to Opinions Please: DigitalOcean Or Linode?

I use Digital Ocean also. They Have tons of guides on how to accomplish what you need.

Activity icon

Replied to Which Path Should I Take To Learn Laravel?

If you aren't using build tools such as npm etc then I recommend starting with tailwind by itself and learn how to customize the tools and commands. Once you get the hang of that then implement tailwind with laravel to understand webpack.

Customize development environment to work with tailwind or any css framework, and eventually laravel. If you use vscode search for addon laravel pack and learn how to setup those up for specific workspace.

Try to utilize the command line tools such as php artisan to generate models, controllers, etc (php artisan make:controller TodoController -r, generates a controller with all resource routes)

Learn to setup a server for laravel many methods: Ubuntu nginx/apache Homestead/docker concept

Laravel Documentation - I recommend reread every month because you will come across something you didn't understand at first, but now it is more meaning to you. Laracasts.com Povilas Korop - https://www.youtube.com/channel/UCTuplgOBi6tJIlesIboymGA

Stick with popular packages: https://spatie.be/open-source, etc

Activity icon

Started a new Conversation Livewire Nested Component Not Working

Here is GIF of problem: https://gph.is/g/Z5JDJgw

I have a simple todo app components:

todos.todo-show:

<?php

namespace App\Http\Livewire\Todos;

use Livewire\Component;

class TodoShow extends Component
{
    public $todo;

    public function render()
    {
        return view('livewire.todos.todo-show');
    }
}

todos.todos-list:

<?php

namespace App\Http\Livewire\Todos;

use App\Models\Todo;
use Livewire\Component;

class TodosList extends Component
{
    protected $listeners = ['render'];

    public function render()
    {
        $todos = Todo::latest()->get();

        return view('livewire.todos.todos-list', compact('todos'));
    }
}

todos.todo-form:

<?php

namespace App\Http\Livewire\Todos;

use App\Models\Todo;
use Livewire\Component;

class TodoForm extends Component
{
    public $title;

    public function render()
    {
        return view('livewire.todos.todo-form');
    }

    public function addTodo()
    {
        $this->validate([
            'title' => 'required|min:1',
        ]);

        Todo::create(['title' => $this->title]);
        $this->title = '';

        $this->emitTo('todos.todos-list', 'render');
    }
}

When I add a new todo it duplicates the last todo in the list and doesn't display properly until a full page reload. I expect it to just add the new todo at the top of the list

Here is the nest:

@extends('layouts.app')

@section('content')
<div class="container">
    <livewire:todos.todo-form />
    <livewire:todos.todos-list />
</div>
@endsection

livewire.todos-list.blade.php:

<div class="row flex-column">
    @foreach ($todos as $todo)
        <livewire:todos.todo-show :todo="$todo" :key="$loop->index" />
    @endforeach
</div>

I read in the livewire documentation: "Nested components CAN accept data parameters from their parents, HOWEVER they are not reactive like props from a Vue component."

Not sure if that is the issue.

Nov
18
2 months ago
Activity icon

Replied to How I Can Get All Tickets With Count Replies On It For The Current User

Okay can you post your controller code and the view code you are returning from the controller method?

Activity icon

Replied to How I Can Get All Tickets With Count Replies On It For The Current User

Okay now are you trying to render a view displaying the number of replies for each ticket?

Activity icon

Replied to How I Can Get All Tickets With Count Replies On It For The Current User

I did above.

do you have a file App\Models\User.php, App\Models\Ticket.php, and App\Models\Reply.php?

Can you please post those files?

Activity icon

Replied to How I Can Get All Tickets With Count Replies On It For The Current User

So each user has multiple tickets? and each ticket has multiple replies? Also its not clear if you want the replies for only that user or just all the replies by all users. I think your table for replies isn't setup properly. The setup you have describes a many to many relationship with users and tickets rather than replies. Also I don't know what other columns are on the replies table.

If that is the case on your user model you need:

public function tickets()
{
    return $this->hasMany('App\Models\Ticket');
}

In your ticket model:

public function replies()
{
    return $this->belongsTo('App\Models\Replies');
}

Then in your view you could call like this:

$user->tickets // all the users tickets
$user->tickets->first() // the first ticket in that collection
$user->tickets->first()->replies // the replies for that ticket
$user->tickets->first->replies->where('user_id', $user->id) // the users first ticket with only replies from that user

Then to count:

count($user->tickets->first()->replies)
count($user->tickets->first->replies->where('user_id', $user->id))
Activity icon

Started a new Conversation How To Validate At Least One Required And Only The One Entered?

I want to require atleast one using:

'email' => 'required_without_all:id,dob',
'id' => 'required_without_all:email,dob',
'dob' => 'required_without_all:email,id'

This works fine, but if I try and add validation for the fields like:

'required_without_all:id,dob|email',
'required_without_all:email,dob|digits:4'

If I enter email and not id then it still tries and validates ID even if I have at least one entered. I have tried nullable

Any tips?

Oct
25
3 months ago
Activity icon

Awarded Best Reply on Http Client & Paypal API Invalid Request

Had to add application_context (even though it says its not required...)

Http::withToken($response->json()['access_token'])->post('https://api.sandbox.paypal.com/v2/checkout/orders/'.$request->token.'/capture',[
            'application_context' => [
                'return_url' => route('invoices.index'),
                'cancel_url' => route('payments.cancel')
            ]
        ]);

https://developer.paypal.com/docs/api/orders/v2/#definition-order_capture_request.customized_x_unsupported_3218_order_application_context

Activity icon

Replied to Http Client & Paypal API Invalid Request

Had to add application_context (even though it says its not required...)

Http::withToken($response->json()['access_token'])->post('https://api.sandbox.paypal.com/v2/checkout/orders/'.$request->token.'/capture',[
            'application_context' => [
                'return_url' => route('invoices.index'),
                'cancel_url' => route('payments.cancel')
            ]
        ]);

https://developer.paypal.com/docs/api/orders/v2/#definition-order_capture_request.customized_x_unsupported_3218_order_application_context

Activity icon

Replied to Advanced Query Help

Post models and tables

Possible Models:

Facility: Methods(techs(), files('fileable'))
Tech: Methods(facility(), files()) //table has(facility_id)
File: Methods(facilities(), techs()) //table has(morph(fileable(example: 'App\Models\Facility' or 'App\Models\Tech'), uploader_id/user_id/tech_id))

Then you can pull the data a few different ways:

$facility = Facility::find(id);
$facility->files _> foreach(file $file->tech/uploader_id)
$facility->techs _> foreah(tech $files->if(matches facility id))
Activity icon

Started a new Conversation Http Client & Paypal API Invalid Request

I can't capture this payment does anyone have any tips point me in the right direction? I think I'm missing something from the body of the request, but I have all the required, according to the API documentation. Was wondering if its a Http client issue?

Http::withToken($response->json()['access_token'])->post('https://api.sandbox.paypal.com/v2/checkout/orders/'.$request->token.'/capture');
{"name":"INVALID_REQUEST","message":"Request is not well-formed, syntactically incorrect, or violates schema.","debug_id":"1ba98921ebb38","details":[{"field":"\/","location":"body","issue":"INVALID_SYNTAX","description":"MALFORMED_REQUEST_JSON"}],"links":[{"href":"https:\/\/developer.paypal.com\/docs\/api\/orders\/v2\/#error-INVALID_SYNTAX","rel":"information_link","encType":"application\/json"}]}
Oct
20
3 months ago
Activity icon

Replied to Query Polymorphic Relationship

@sinnbeck User Model

public function invoices()
    {
        return $this->morphMany('App\Models\Invoice', 'billable');
    }

Invoice Model

public function billable()
    {
        return $this->morphTo();
    }
Activity icon

Started a new Conversation Query Polymorphic Relationship

I have a students page with where each student has an invoice for the course, and i want to check the status of each invoice (paid/unpaid) for each student.

$event->invoices->where('paid', false)->where('billable_id', $student->id)

That retrieves it fine, but this is a polymorphic relationship so sometimes the billable_id might reference another model. How can I search through only users.

Point me in the right direction! Thanks

Oct
18
3 months ago
Activity icon

Started a new Conversation Many To Many Polymorphic

I have the following: Events are schedulable and can have courses OR services. This works fine I can attach multiple courses OR services per event, but if the event is for a course then there is actually only ever 1 course. So instead of return a collection how can I either save just 1 course or have it return without having to:

$event->courses->first()->name;

rather

$event->course->name;

Also thought about also putting another morph directly on the event table, but then this over complicates the goal. I think...

If you have tips to point me in the right direction I would appreciate it. I'm not entirely sure about the best way to go about this.

Thanks

Oct
15
3 months ago
Activity icon

Started a new Conversation Alisa Not Working

I'm trying to use an alias for the Mula Pkg https://github.com/lukeraymonddowning/mula

config/app.php

'Mula' => Lukeraymonddowning\Mula\Facades\Mula::class
composer dump-autoload
php artisan config:clear
php artisan config:cache

I can get it to work in blade if I use

{{Lukeraymonddowning\Mula\Facades\Mula::create($topic->price, 'USD')}}

but I just want to ref

Mula::create($topic->price, 'USD')

Can anyone point me in the right direction?

Sep
29
3 months ago
Activity icon

Awarded Best Reply on Algolia Installation Failed

I had to install specific version for php 7.4

sudo apt-get install php7.4-curl
Activity icon

Replied to Algolia Installation Failed

I had to install specific version for php 7.4

sudo apt-get install php7.4-curl
Activity icon

Started a new Conversation Algolia Installation Failed

I am following the documentation on laravel 8.x website for scout and when I run:

composer require algolia/algoliasearch-client-php

it says

Using version ^2.7 for algolia/algoliasearch-client-php
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for algolia/algoliasearch-client-php ^2.7 -> satisfiable by algolia/algoliasearch-client-php[2.7.0].
    - algolia/algoliasearch-client-php 2.7.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.

  To enable extensions, verify that they are enabled in your .ini files:
    - /etc/php/7.4/cli/php.ini
    - /etc/php/7.4/cli/conf.d/10-mysqlnd.ini
    - /etc/php/7.4/cli/conf.d/10-opcache.ini
    - /etc/php/7.4/cli/conf.d/10-pdo.ini
    - /etc/php/7.4/cli/conf.d/15-xml.ini
    - /etc/php/7.4/cli/conf.d/20-bcmath.ini
    - /etc/php/7.4/cli/conf.d/20-calendar.ini
    - /etc/php/7.4/cli/conf.d/20-ctype.ini
    - /etc/php/7.4/cli/conf.d/20-dom.ini
    - /etc/php/7.4/cli/conf.d/20-exif.ini
    - /etc/php/7.4/cli/conf.d/20-ffi.ini
    - /etc/php/7.4/cli/conf.d/20-fileinfo.ini
    - /etc/php/7.4/cli/conf.d/20-ftp.ini
    - /etc/php/7.4/cli/conf.d/20-gd.ini
    - /etc/php/7.4/cli/conf.d/20-gettext.ini
    - /etc/php/7.4/cli/conf.d/20-iconv.ini
    - /etc/php/7.4/cli/conf.d/20-json.ini
    - /etc/php/7.4/cli/conf.d/20-mbstring.ini
    - /etc/php/7.4/cli/conf.d/20-mysqli.ini
    - /etc/php/7.4/cli/conf.d/20-pdo_mysql.ini
    - /etc/php/7.4/cli/conf.d/20-phar.ini
    - /etc/php/7.4/cli/conf.d/20-posix.ini
    - /etc/php/7.4/cli/conf.d/20-readline.ini
    - /etc/php/7.4/cli/conf.d/20-shmop.ini
    - /etc/php/7.4/cli/conf.d/20-simplexml.ini
    - /etc/php/7.4/cli/conf.d/20-sockets.ini
    - /etc/php/7.4/cli/conf.d/20-sysvmsg.ini
    - /etc/php/7.4/cli/conf.d/20-sysvsem.ini
    - /etc/php/7.4/cli/conf.d/20-sysvshm.ini
    - /etc/php/7.4/cli/conf.d/20-tokenizer.ini
    - /etc/php/7.4/cli/conf.d/20-xmlreader.ini
    - /etc/php/7.4/cli/conf.d/20-xmlwriter.ini
    - /etc/php/7.4/cli/conf.d/20-xsl.ini
  You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.

Installation failed, reverting ./composer.json to its original content.

I then check curl

dpkg -l curl

returns

Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version           Architecture Description
+++-==============-=================-============-======================================>
ii  curl           7.68.0-1ubuntu2.2 amd64        command line tool for transferring dat>

I'm running nginx ubuntu 20.04

Any tips?

Activity icon

Awarded Best Reply on Installing Scout

needed to change

/

to

\
Activity icon

Replied to Installing Scout

needed to change

/

to

\
Activity icon

Started a new Conversation Installing Scout

I'm trying to install scout using the documentation, but I get this error:

Unable to locate publishable resources.
Publishing complete.

When I run:

php artisan vendor:publish --provider="Laravel/Scout/ScoutServiceProvider"
Aug
28
4 months ago
Activity icon

Replied to How To Sum Polymorphic Through Relationship

@sinnbeck The first one returns

"20.00"

The second one returns

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'services.price' in 'field list' (SQL: select sum(`services`.`price`) as aggregate from `events`)

Yes I want to get the total sum of the prices for all the services for each event attached to the invoice.

Activity icon

Started a new Conversation How To Sum Polymorphic Through Relationship

Hey not sure if the question is right, but I have:

$invoices->first()->events()->first()->services->first()->price;

I would like to sum the total price (something like this, if invoice has 2 events attached):

$invoices->first()->events->sum('services.price');

Can someone point me in the right direction?

Thanks, Alex

Aug
17
5 months ago
Activity icon

Awarded Best Reply on How To Query Polymorphic Relationship

Got it thanks!

$events = Event::has('courses')->with('courses')->whereHas('courses', function ($query) use ($course) {
            $query->where('id', $course->id);
        })->get();
Activity icon

Replied to How To Query Polymorphic Relationship

Got it thanks!

$events = Event::has('courses')->with('courses')->whereHas('courses', function ($query) use ($course) {
            $query->where('id', $course->id);
        })->get();
Activity icon

Started a new Conversation How To Query Polymorphic Relationship

I'm trying to select an event that is a "course" where the course is a certain course.

$events = Event::has('courses')->with('courses')->where('schedulables.scheduleable_id', $course->id)->get();

Could someone point me in the right direction?

Thanks, Alex

Aug
13
5 months ago
Activity icon

Replied to Best Way To Convert This String To Time?

Thanks guys I got it. I had the create from Format wrong... should have been m-d-Y based upon input.