Skip to content

Broken default value for Code/JSON fields #3736

@jacob418

Description

@jacob418
  • Laravel Version: 8.75.0
  • Nova Version: 3.30.0
  • PHP Version: 8.0.9
  • Database Driver & Version: Docker-Image: postgres:13
  • Operating System and Version: Linux 5.4.0-96-generic
  • Browser type and version: Google Chrome/96.0.4664.110

Description:

For fields of type \Laravel\Nova\Fields\Code with the mode = application/json option it is not possible to define default values via the \Laravel\Nova\Fields\Code::default method.

Detailed steps to reproduce the issue on a fresh Nova installation:

  1. Create a Laravel/Nova Project
  2. Create a Model/Table with JSON column
  3. Create a Nova Resource for the Model
  4. Add a Code field and set the JSON-Option
  5. Set '{}' as default value for the Field
  6. Browser: open the 'create a new resource' form for the Model in Nova UI

Expected behavior

  • Field gets default-value ({}) displayed as content

Observed behavior

  • Field gets null displayed as content

Reason

The problem originates in \Laravel\Nova\Fields\Code::resolveAttribute.
When the JSON option is set, the current value is encoded as JSON in line 66/56.
However, encoding null with JSON will result in the string 'null'.

Later in the \Laravel\Nova\Fields\Field::jsonSerialize method, the default value is resolved only if the current value is nullish.
However the string 'null' is not nullish (even though the encoded value is nullish) so the default value will not be resolved.

Workaround

A way to work around this by extending the code field with your own class:

app/Nova/Fields/code.php

<?php

namespace App\Nova\Fields;

use Laravel\Nova\Fields\Field;

class Code extends \Laravel\Nova\Fields\Code
{
    protected function resolveAttribute($resource, $attribute): mixed
    {
        $value = Field::resolveAttribute($resource, $attribute);

        if ($this->json && !is_null($value)) {
            return json_encode($value, $this->jsonOptions ?? JSON_PRETTY_PRINT);
        }

        return $value;
    }
}

In line 20 we ensure the value to encode is not null before serializing it.
However this introduces a problem in scenarios where a null value is expected to be inserted into db in certain cases so use the workaround with caution! ⚠️⚠️⚠️

Metadata

Metadata

Assignees

No one assigned

    Labels

    requestFeature Request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions