1

I have a yii2 model and relations.
Yii2 response format set to JSON.
I want to return model with its relationships (one-to-many) and so far everything was fine.

However, in this case for one of model relationships JSON response encodes into JSON object {}, not array []. And I can't figure out why exactly? For other relationships it is an array.

Below is var_dump of a model. The problematic relations is items

/backend/controllers/TasksController.php:181:
object(app\models\Task)[163]
  private '_attributes' (yii\db\BaseActiveRecord) => 
    array (size=6)
      'id' => int 9
      'title' => string 'Sample dnewsd' (length=13)
      'mode' => string 'onlyads' (length=7)
      'deployed' => int 0
      'start_time' => string '2017-11-16 00:00:00' (length=19)
      'end_time' => null
  private '_oldAttributes' (yii\db\BaseActiveRecord) => 
    array (size=6)
      'id' => int 9
      'title' => string 'Sample dnewsd' (length=13)
      'mode' => string 'onlyads' (length=7)
      'deployed' => int 0
      'start_time' => string '2017-11-16 00:00:00' (length=19)
      'end_time' => null
  private '_related' (yii\db\BaseActiveRecord) => 
    array (size=3)
      'items' => 
        array (size=2)
          0 => 
            object(app\models\TaskItem)[178]
              ...
          2 => 
            object(app\models\TaskItem)[201]
              ...
      'devices' => 
        array (size=0)
          empty
      'deviceGroups' => 
        array (size=0)
          empty

Here is the JSON return when I edit model:

{
    "status": "ok",
    "data": {
        "id": 9,
        "title": "Sample task",
        "mode": "onlyads",
        "deployed": 0,
        "start_time": "2017-11-16 00:00:00",
        "end_time": null,
        "items": {
            "0": {
                "id": 2,
                "image_url": "/media/lightboxes/pictures/ad_.jpg",
                "duration": 20,
                "task_id": 9
            },
            "2": {
                "id": 46,
                "image_url": "/media/lightboxes/pictures/ad_46.jpg",
                "duration": 20,
                "task_id": 9
            }
        },
        "devices": [],
        "deviceGroups": []
    }
}

You can see that items is not a JSON array: items : {}

In another action - GET the same model the returned JSON has items: []:

{
    "status": "ok",
    "data": {
        "id": 9,
        "title": "Sample dnewsd",
        "mode": "onlyads",
        "deployed": 0,
        "start_time": "2017-11-16 00:00:00",
        "end_time": null,
        "items": [
            {
                "id": 2,
                "image_url": "/media/lightboxes/pictures/ad_.jpg",
                "duration": 20,
                "task_id": 9
            },
            {
                "id": 46,
                "image_url": "/media/lightboxes/pictures/ad_46.jpg",
                "duration": 20,
                "task_id": 9
            }
        ],
        "devices": [],
        "deviceGroups": []
    }
}

Here is var_dump for the same model in GET action:

/srv/www/erp-ang/backend/controllers/TasksController.php:55:
object(app\models\Task)[163]
  private '_attributes' (yii\db\BaseActiveRecord) => 
    array (size=6)
      'id' => int 9
      'title' => string 'Sample dnewsd' (length=13)
      'mode' => string 'onlyads' (length=7)
      'deployed' => int 0
      'start_time' => string '2017-11-16 00:00:00' (length=19)
      'end_time' => null
  private '_oldAttributes' (yii\db\BaseActiveRecord) => 
    array (size=6)
      'id' => int 9
      'title' => string 'Sample dnewsd' (length=13)
      'mode' => string 'onlyads' (length=7)
      'deployed' => int 0
      'start_time' => string '2017-11-16 00:00:00' (length=19)
      'end_time' => null
  private '_related' (yii\db\BaseActiveRecord) => 
    array (size=3)
      'items' => 
        array (size=2)
          0 => 
            object(app\models\TaskItem)[178]
              ...
          1 => 
            object(app\models\TaskItem)[184]
              ...
      'devices' => 
        array (size=0)
          empty
      'deviceGroups' => 
        array (size=0)
          empty

Any clue why could this happen?

7
  • 2
    your arrays need to have consecutive indexes starting from 0 (in your first case you have your items indexed 0, 2 respectively) Commented Nov 9, 2017 at 1:05
  • also are you just returning an ActiveRecord or are you calling ->toArray(), Commented Nov 9, 2017 at 1:09
  • @csminb. Well, that was not obvious.. Thanks. If you've encountered this before, maybe you know - how would I reindex values of relation array? Since $model->items is a read-only property in Yii I can not do something like $model->items = array_values($model->items). Reload the model from db? Commented Nov 9, 2017 at 1:14
  • @csminb. Yii2 should call ->toArray() automatically when it encodes an ActiveRecord to JSON. Arrayable interface. Commented Nov 9, 2017 at 1:16
  • i'm not sure how it does it internally, but calling it manually might give you better control over what fields/relations you want to show ($task->toArray([], ['items', 'devices']) typically relations should not be converted when calling toArray unless you specify extra fields Commented Nov 9, 2017 at 1:28

1 Answer 1

1

arrays need to have consecutive indexes starting from 0,
if you need to re-index an already loaded relation you can run

$task->populateRelation('items', array_values($task->items));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.