Crud: Errors if cast json field to array as Docs say

Created on 30 Jun 2018  路  8Comments  路  Source: Laravel-Backpack/CRUD

I tried to seek help on the gitter chatroom earlier and decide to report this bug

Copy of the chat logs:
Hi, I'm trying to addField (for a json field) and I keep getting:

json_decode() expects parameter 1 to be string, array given

my field is casted as array of course as the docs recommend
Any idea what's wrong?
If I remove the cast to array in my model, it works!
That runs against the docs so I am confused

Z @ziming 00:06
Anyone here?

Abby @AbbyJanke 00:34
@ziming can you post some code either here or to a gist so we can take a look?

Z @ziming 00:54
Thanks Abby. Here you go.
In my model I cast shop_information to array as seen here
https://cl.ly/segJ

Then in my CrudController my addField I have the following fake field
https://cl.ly/seyg

But when I am in list view or edit view, I will get an error
Here is a screenshot of the logs
https://cl.ly/sesx

Abby @AbbyJanke 00:57
what type of field are you looking for? just a plain text?

Z @ziming 00:57
https://cl.ly/sf6r

my shop_information field is a json field
name is 1 of the fields in that json field
Reading the docs, it says if my json field is not named 'extras' I must cast it as array
which I already did. All my json fields are cast as array before using backpack
Yet it give me this error
When I remove the cast to array, the error dissapear and everything works fine in backpack but other parts of my codebase requires my json fields to be cast as array.
The backpack docs itself said so too:

https://cl.ly/sdun

Abby @AbbyJanke 01:34
public function getShopInformationAttribute($value) {
return json_encode($value);
}
if you add that to your model it will fix it for now.

Z @ziming 01:35
Problem is other parts of my codebase... expect an array back
various other json related packages such as spatie/schemaless also expect json fields to be casted as array

My backpack/crud is "backpack/crud": "^3.4". I only installed backpack today

I have protected $fakeColumns = ['shop_information']; too in my model too

[2018-06-30 17:47:41] local.ERROR: json_decode() expects parameter 1 to be string, array given {"userId":1,"email":"[email protected]","exception":"[object] (ErrorException(code: 0): json_decode() expects parameter 1 to be string, array given at /Users/my-name/php-apps/my-app/vendor/backpack/crud/src/CrudTrait.php:82)

Bug

All 8 comments

My suggested fix would be:

https://cl.ly/sdpP

Why are you trying to save it as a fake? - Do you not have a column in your database called 'shop_information?'

Hi @OwenMelbz

shop_information is a json field/column in the table i inherited. 1 of the many subfields of shop_information is 'name' which I'm trying to update

According to the docs to update a subfield in a json field (in my case name or any other subfield in shop_information).

We should use fake fields.

https://laravel-backpack.readme.io/docs/advanced-features

https://cl.ly/seIO

The docs also say to cast it as array too. So my shop_information field is casted as array and should work based on the docs. Several popular laravel packages expect json fields to be casted as array too

https://cl.ly/sdun (Backpack docs)

https://cl.ly/seCl (Laravel Docs)

https://cl.ly/seP7 (spatie/laravel-schemaless-attributes Docs)

Thanks!

Despite the fact this is an atrocious bug report, it does seem to be a bug.

  • Please try not to use a long chat conversation, no matter how valid, as the beginning of a bug report
  • And why all the links to https://cl.ly/ (markup supports links like this natively).

Thank you for accepting my atrocious bug report!

Hello! What is the status of solving the problem? I've been trying to solve this problem for a week already. I'm trying to do a similar fake column in which I'm going to store data, but I get an error about

json_decode() expects parameter 1 to be string, array given

protected $table = 'services';
protected $primaryKey = 'id';
public $timestamps = true;
protected $fakeColumns = ['extras', 'attributes', 'options'];
protected $fillable = ['title', 'slug', 'status', 'geo', 'extras', 'attributes', 'options', 'images', 'created_at', 'updated_at'];
protected $casts = [
    'geo' => 'array',
    'extras' => 'array',
    'attributes' => 'array',
    'options' => 'array',
    'images' => 'array',
    ];
$fields = OptionGroup::where('belongs_to', 'rent')->where('active', true)->get();
  foreach($fields as $field){

    $field_options = Option::where('option_group_id', $field->id)->get();
        foreach($field_options as $field_option){
            $this->crud->addField([
              'name' => $field_option->title, // Fake field name in base.
              'label' => $field_option->title, // Fake label.
              'type' => 'text',
              'wrapperAttributes' => [
                   'class' => 'form-group col-md-12'
              ],
              'fake' => true, // Set fake true
              'store_in' => $field->kind, // If field extras colum it work, but attributes or options dont work.
              'tab' => $field->title, // Parent of field name.
              ]);
    }
}

As you can see the columns created, and when you create in them even the data is saved.

image

Again I am writing. I decided for myself a problem. This Pull#1362 helped me use my columns. It is worthwhile to understand why this happens. But with this solution array and object types work.

I changed

if (! is_object($this->{$column})) {
    $column_contents = json_decode($this->{$column});
}

On

if (isset($this->attributes[$column]) && !is_object($this->attributes[$column])) {
    $column_contents = json_decode($this->attributes[$column]);
}

Hi guys,

I just went through this thread again and again - but NOW I think I understand it:

  • $this->{column} gets the column AFTER the cast has been applied;
  • $this->attributes[$column] gets the column BEFORE the case has been applied;

In this case, BEFORE is what we needed. That will make addFakes work regardless. I'm pretty sure this will not affect anyone negatively, so I've created an alternative PR #1533 that I've merged into master and will be available with a composer update in a few hours/days, after I bundle it with a few more non-breaking changes.

Thanks a lot for reporting this guys, and providing a solution!
Cheers!

Was this page helpful?
0 / 5 - 0 ratings