Question

I'm using Laravel as an API an AngularJS front end. Part of this is when the app loads I preload the app with the user signed in to save an http request.

Is there an recursive ->toArray() that will loop through all properties and convert all eloquent models to jsonable arrays?

I have made one manually in L3 but have not found something similar in the docs.

PortalController.php $user->medications is an array of eloquent objects.

Does not work

<?php

class PortalController extends BaseController {

    public function getIndex()
    {
        $user = User::find(Auth::user()->id);
        $user->healthProfile = $user->getHealthProfile();
        $user->medications = $user->getItems('medication');

        return View::make('portal.index', [
            'init' => [
                             // The array of medications disappear.
                'user' => $user->toArray()
            ]
        ]);
    }

}

Works

<?php

class PortalController extends BaseController {

    public function getIndex()
    {
        $user = User::find(Auth::user()->id);
        $user->healthProfile = $user->getHealthProfile();
        $user->medications = $user->getItems('medication')->toArray(); //boop

        return View::make('portal.index', [
            'init' => [
                            // The array of medications still exists.
                'user' => $user->toArray()
            ]
        ]);
    }

}

views/portal/index.blade.php

<script>
    (function() {

        'use strict';

        angular.module('portal.init', [])

            .service('Init', [function() {
                return function() {
                    return {{ json_encode($init) }};
                }
            }]);

    })();
</script>

My L3 class that converts recursively, hoping there is a native solution.

    public static function to_array($models)
    {
        if ($models instanceof Laravel\Database\Eloquent\Model) {
            $models = $models->to_array();
        }

        if (is_array($models)) {
            foreach ($models as $key => $value) {
                $models[$key] = self::to_array($value);
            }
        }

        return $models;
    }

Update

// models/User.php

    // ..etc.

public function allergies()
{
    return $this->hasMany('PortalItem', 'portal_user_id')
        ->whereKey('allergy');
}

public function medications()
{
    return $this->hasMany('PortalItem', 'portal_user_id')
        ->whereKey('medication');
}

public function symptoms()
{
    return $this->hasMany('PortalItem', 'portal_user_id')
        ->whereKey('symptom');
}

    // ..etc.

// controllers/PortalController.php

<?php

class PortalController extends BaseController {

    public function getIndex()
    {
        $user = User::with('healthProfile', 'medications', 'allergies', 'symptoms', 'procedures', 'immunizations')
            ->whereId(Auth::user()->id)
            ->first();

        return View::make('portal.index', [
            'init' => [
                'user' => $user->toArray()
            ]
        ]);
    }

}
Was it helpful?

Solution

Why dont you just use the native toJson() method on the eloquent class?

$user->toJson();

so in your controller it would be

 return View::make('portal.index', [
        'init' => [
                         // The array of medications disappear.
            'user' => $user->toJson()
        ]
    ]);

If you want medications included in the JSON conversion - you must first eager load them.

$user = User::with('medications')->all();

OTHER TIPS

Surely healthProfile and medications could be made into relationships?

If you do this, you can then do something like this.

class PortalController extends BaseController {

    public function getIndex()
    {
        // No need to create a new query for something we already have
        $user = Auth::user();
        $user->load('healthProfile', 'medications');

        return View::make('portal.index', [
            'init' => [
                'user' => $user->toArray()
            ]
        ]);
    }

}

Then simply, in the template (I assume you're using blade), you would just do:

{{ json_encode($init) }}

The assumption here is that you're actually using the php/blade variable to prepopulate a variable within javascript, or at least, have it output.

There is the toJson() method provided by laravel, but that doesn't suit your needs here. Try setting up the relationships and using json_encode() in the blade/template file, and that should work. Any other questions, let me know.

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top