Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

sheldonscott's avatar

Array & JSON Casting

I am trying to send some data along to Algolia through the toSearchableArray. Any strings I have stored in my DB are sending along fine, but I hit a roadblock when trying to push nested JSON data along—the information is being sent as a string with characters escaped.

This is a sample of the nested object that I am storing in my table (MySQL with a JSON data type):

[
    {
        "id": 19, 
        "name": "Mathematics", 
        "short": "Math"
    }, 
    {
        "id": 23, 
        "name": "Science", 
        "short": "Science"
    }, 
    {
        "id": 14, 
        "name": "Health and Life Skills", 
        "short": "Health"
    }
]

My model looks like this:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Resource extends Model
{
    use Searchable;
    protected $primaryKey = 'objectID';

    public function toSearchableArray()
    {
        $data = $this->toArray();

        $data['grades'] = explode(';', $data['grades']);
        $data['units'] = explode(';', $data['units']);

        return $data;
    }
}

I get an output that looks like this:

array:22 [
  "objectID" => 1
  "name" => "Resource #1"
  "slug" => "resource-1"
  "write_up" => """
    This is an example write up.
    """
  "author" => "johnny"
  "type_name" => "Lesson Plan"
  "language" => "English"
  "grades" => array:3 [
    0 => "Kindergarten"
    1 => "Grade 1"
    2 => "Grade 4"
  ]
  "subjects" => "[{"id": 19, "name": "Mathematics", "short": "Math"}, {"id": 23, "name": "Science", "short": "Science"}, {"id": 14, "name": "Health and Life Skills", "short": "Health"}]"
  "units" => array:2 [
    0 => "Unit A"
    1 => "Unit B"
  ]
  "main_image" => "https://dummyimage.com/250x325/000000/fff.png&text=Just+a+Test"
  "loves" => 88
  "downloads" => 280
  "created_at" => "2018-01-01 13:26:47"
  "updated_at" => "2018-01-02 10:10:32"
]

As you can see, the 'subjects' attribute is being stored as a string. I know there is attribute casting in 5.5 (I am running 5.5), but I am not too clear on how I would implement the example they have for Array & JSON Casting in my work above. https://laravel.com/docs/5.5/eloquent-mutators#attribute-casting

Would anyone be willing to show me an example?

0 likes
3 replies
sheldonscott's avatar
sheldonscott
OP
Best Answer
Level 2

I'll post the answer that was provided to me by the folks at Algolia for anyone's future reference:

You can do it manually, just the way you explode grades and units

public function toSearchableArray()
  {
    $data = $this->toArray();

    $data['grades'] = explode(';', $data['grades']);
    $data['units'] = explode(';', $data['units']);

    $data['subjects'] = json_decode($this->subjects, true);

    return $data;
  }

But I’d prefer relying on Laravel to do it automatically with Attribute Casting: (note the new $casts attribute)

class Resource extends Model
  {
    use Searchable;
    protected $primaryKey = 'objectID';

    protected $casts = [
      'subjects' => 'array',
    ];

    public function toSearchableArray()
    {
      $data = $this->toArray();

      $data['grades'] = explode(';', $data['grades']);
      $data['units'] = explode(';', $data['units']);

      return $data;
    }
  }

https://stackoverflow.com/questions/48065785/laravel-array-json-casting-to-algolia

1 like
adavie's avatar

Sigh. I have the same problem. One model, $cast as array works fine.

    protected $casts = [
      'state' => 'array'
    ];

In another case, despite the same $cast expression, after wasting 10 hours, I finally came up with this work around:

$step->state = is_array($step->state) ? $step->state : json_decode($step->state) ;

This is scattered through out my controller for the model.

I really can't understand why it works flawlessly in one case, and in a near identical model, it fails totally.

Laravel 5.4 also.

1 like

Please or to participate in this conversation.