Framework: API Resource Carbon Dates rendering as full arrays

Created on 26 Jul 2018  路  3Comments  路  Source: laravel/framework

  • Laravel Version: 5.5.40
  • PHP Version: 7.2.7
  • Database Driver & Version: MySQL 5.7.22

Description:

Laravel API Resource exports Carbon dates as arrays.

Steps To Reproduce:

As illustrated in the code, sending back $this->created_at will actually dump the entire Carbon object as an array, rather than the string version.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

/**
 * Resource designed to work with Eloquent Model
 *
 * @package App\Http\Resources
 */
class DemoResource extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request $request
     *
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
            'deleted_at' => $this->deleted_at,
        ];
    }
}

Steps To Resolve:

Typecasting (string) for the Carbon Dates fixes it. If this is intended, that's fine, it just seems really odd to do this extra step. It gives more flexibility, but it kind of takes the whole Laravel Magic out of things.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

/**
 * Resource designed to work with Eloquent Model
 *
 * @package App\Http\Resources
 */
class DemoResource extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request $request
     *
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'created_at' => (string) $this->created_at,
            'updated_at' => (string) $this->updated_at,
            'deleted_at' => (string) $this->deleted_at,
        ];
    }
}

Most helpful comment

You can choose another HTTP response representation by calling Illuminate\Support\Carbon@serializeUsing(). e.g., put the following in your AppServiceProvider:

Carbon::serializeUsing(function (Carbon $timestamp) {
    return $timestamp->toIso8601ZuluString();
});

which is more moment.js-friendly.

All 3 comments

The magic is getting a carbon object from a date field in your database. If you don't want dates to be cast into carbon objects, don't add them to the model's $dates array.

You can choose another HTTP response representation by calling Illuminate\Support\Carbon@serializeUsing(). e.g., put the following in your AppServiceProvider:

Carbon::serializeUsing(function (Carbon $timestamp) {
    return $timestamp->toIso8601ZuluString();
});

which is more moment.js-friendly.

You can also do it this way in your model :

https://laravel.com/docs/7.x/eloquent-serialization#date-serialization

Was this page helpful?
0 / 5 - 0 ratings