Search code examples
javascriptlaraveldateiso8601

Laravel complaining about 'trailing data' when sending ISO-formatted date in JSON to server?


I have a Laravel model with a date field, archivedAt. This has been set in the $dates array on the model, like so:

Contact model

class Contact extends Model
{
    /**
     * The name of the table in the database.
     *
     * @laravel-table-name
     *
     * @var string
     */
    protected $table = 'Contacts';

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = [
        'createdAt',
        'updatedAt',
        'archivedAt'
    ];

}

When I try to send a JSON payload to the sever over GraphQL, I get the following response back:

{
    "data": {
        "editContact": null
    },
    "errors": [
        {
            "message": "Unexpected data found.\nTrailing data",
            "locations": [
                {
                    "line": 2,
                    "column": 3
                }
            ]
        }
    ]
}

Of course, the GraphQL libraries for Laravel are terrible and don't include the full stack trace or any additional information, but this appears to be a problem with me setting the archivedAt field. Here's how I'm doing that:

{
    "operationName": null,
    "variables": {
        "contactEditForm": {
            "id": "2",
            "name": "Maybelle Collier",
            "email": "cletus49@example.org",
            "phone": "+1 (997) 381-8483",
            "archivedAt": "2018-03-19T00:07:57.191Z",
            "createdAt": "2018-03-18 23:57:30",
            "updatedAt": "2018-03-18 23:57:30"
        }
    },
    "query": "mutation ($contactEditForm: ContactEditForm!) {\n  editContact(contactEditForm: $contactEditForm) {\n    id\n    name\n    __typename\n  }\n}\n"
}

As you can see, archivedAt is an ISO8601 formatted string, which was produced on my client with:

(new Date())->toISOString();

This is then supposed to be saved on the GraphQL server with a mutation, like so:

public function resolve($root, $args, $context, ResolveInfo $info)
{
    $contact = Contact::find($args['contactEditForm']['id']);
    $contact->fill($args['contactEditForm']);
    $contact->save();

    return $contact;
}

Why does Laravel not like this?


Solution

  • I've never had this issue but, according to Laravel's Docs, if you set the field in the $dates property, to be correctly mutated:

    When a column is considered a date, you may set its value to a UNIX timestamp, date string (Y-m-d), date-time string, and of course a DateTime / Carbon instance, and the date's value will automatically be correctly stored in your database:

    So, apparently, no ISO string dates allowed for the mutator and therefore either you set it to one of these formats, defining an acessor (like this) or remove it from the $dates and handle it yourself

    http://carbon.nesbot.com/docs/#api-commonformats