SOLVED: Need guidance with Carbon Casting

I tried to follow the example in the docs but am not getting the results I need.

In my component:

class StaffEditor extends Component
{
    public $dob = 'birthday';
    public $anniversary = 'startday';

    protected $casts = [
        'dob' => 'date',
        'startday' => 'date',
    ];

    public function mount($id)
    {
        $this->userID = $id;
        $fetched = User::query()
            ->with('departments', 'manager', 'office')
            ->whereId($id)
            ->first();

        $this->dob = $fetched->dob;
        $this->anniversary = $fetched->anniversary;
    } // end function

    public function getBirthday()
    {
        return ($this->dob ? $this->dob->format('Y-m-d') : null);
    } // end function

    public function getStartday()
    {
        return ($this->anniversary ? $this->anniversary->format('Y-m-d') : null);
    } // end function

    public function render()
    {
        return view('_livewire.staff.staff-editor');
    } // end function

    

In my blade:

<div class="w-1/3">
                        <label class="tw-label">Birthday</label>
                        <input type="text" class="tw-input"
                               wire:model="dob">
                    </div>
                    <div class="w-1/3">
                        <label class="tw-label">Start Date</label>
                        <input type="text" class="tw-input"
                               wire:model="anniversary">
                    </div>

Results: image below as coded and if I comment out $this->anniversary = $fetched->anniversary;

In your $casts array, you have startday instead of anniversary.

Explains why they error occurs and I will fix that. Any idea why the formatting is messed up? I am formatting “Y-m-d” and getting Fri Jul 27 2018 00:00:00 GMT-0500.

If this is a direct copy and paste, there are a few issues here.

    public $dob = 'birthday'; 
    public $anniversary = 'startday';

First you are assigning strings here that carbon would try to turn into a date, but would have no idea how. But that doesn’t matter because then in your mount() method, you are reassigning them to what is in the database.

    $this->dob = $fetched->dob;
    $this->anniversary = $fetched->anniversary;

So that makes the first part unneeded, they can just be declared without being set. If that’s there to help you, just make them comments:

    public $dob; //birthday
    public $anniversary; //startday

Now these 2 methods, I’m not sure what your end game is here:

    public function getBirthday()
    {
        return ($this->dob ? $this->dob->format('Y-m-d') : null);
    } // end function

    public function getStartday()
    {
        return ($this->anniversary ? $this->anniversary->format('Y-m-d') : null);
    } // end function

You are not referencing them anywhere in your code, so they aren’t being hit, and that format isn’t being done. If it’s meant to be a computed property, I suggest reading through the docs some more about those because they aren’t named correctly, and you can’t bind computed properties.

Here’s what the result would be for what I’m guessing you are trying to accomplish:

class StaffEditor extends Component
{
    public $dob; //birthday
    public $anniversary; //startday;

    public function mount($id)
    {
        $this->userID = $id;
        $fetched = User::query()
            ->with('departments', 'manager', 'office')
            ->whereId($id)
            ->first();

        $this->dob = $fetched->dob->format('Y-m-d');
        $this->anniversary = $fetched->anniversary->format('Y-m-d');
    } // end function


    public function render()
    {
        return view('_livewire.staff.staff-editor');
    } // end function

}

You don’t need to cast them to dates because you aren’t working with carbon anywhere in here, and even if they are coming out of your database as a carbon instance ->format() is already converting them to a string, so livewire doesn’t need to know to do that.

This also only covers your initial load, there isn’t anything here yet for what to do when the user starts changing stuff.

On a side note, this:

$fetched = User::query()
    ->with('departments', 'manager', 'office')
    ->whereId($id)
    ->first();

can be accomplished by:

$fetched = User::with('departments', 'manager', 'office')->find($id);

Find() is the equivalent of whereId() and first() rolled into one. There are very few scenarios in everyday use where you have to reach for query(), and a general rule of thumb, it will never be when you can use Model:: syntax.

Thank you … I was getting all messed up trying to grasp the cast concept in the docs.

Here’s my working refactor

class StaffEditor extends Component
{
    public $user;
    public $userID = null;
    public $badge;
    public $first_name;
    public $last_name;
    public $email;
    public $title;
    public $office_id;
    public $extension;
    public $direct_line;
    public $manager_id;
    public $dob;
    public $anniversary;
    public $defaultPW = null;

    public function mount($id)
    {
        $this->userID = $id;
        $fetched = User::query()
            ->with('departments', 'manager', 'office')
            ->find($id);

        $cleanLastName = ucfirst(preg_replace("/[^A-Za-z]/", '', strtolower($fetched->last_name)));
        $dpw = '!' . $cleanLastName . '@uam';
        $this->defaultPW = $dpw;

        $this->user = $fetched;
        $this->badge = $fetched->badge;
        $this->first_name = $fetched->first_name;
        $this->last_name = $fetched->last_name;
        $this->email = $fetched->email;
        $this->title = $fetched->title;
        $this->office_id = $fetched->office_id;
        $this->extension = $fetched->extension;
        $this->direct_line = $fetched->direct_line;
        $this->manager_id = $fetched->manager_id;
        $this->dob = $this->getBirthday($fetched);
        $this->anniversary = $this->getStartday($fetched);
    } // end function

    public function getBirthday($user)
    {
        return ($user['dob'] ? $user['dob']->format('Y-m-d') : null);
    } // end function

    public function getStartday($user)
    {
        return ($user['anniversary'] ? $user['anniversary']->format('Y-m-d') : null);
    } // end function

    public function render()
    {
        return view('_livewire.staff.staff-editor');
    } // end function

    /*******************************/

    public function getDepartmentsProperty()
    {
        $depts = Department::all();
        $departments = [];

        if(!$this->user['departments']) {
            foreach($depts as $dept) {
                $departments[$dept->display] = false;
            } // end foreach
        } else {
            $uDepts = collect($this->user['departments'])->pluck('id');
            foreach($depts as $dept) {
                if(in_array($dept->id, $uDepts->toArray())) {
                    $departments[$dept->display] = true;
                } else {
                    $departments[$dept->display] = false;
                } // end if
            } // end foreach
        } //end if

        return $departments;
    } // end function

    public function deptToggle($deptID)
    {
        $dept = Department::whereId($deptID)->first();
        $this->user->toggleDepartment($dept);
    } // end function

    public function getManagersProperty()
    {
        return User::whereCanManage(true)->orderBy('last_name')->get();
    } // end function

    public function getOfficesProperty()
    {
        return Office::all();
    } // end function

    public function persist()
    {
        //$this->emit();
    } // end function

    public function tuggle($fld)
    {
        $this->user[$fld] = ! $this->user[$fld];
    } // end function
}

I really appreciate your taking the time to assist!