jeudi 26 novembre 2015

Angular + Laravel 5.1: Saving a $resource with related objects

I got lost in this situation and would like to receive some feedback/advice on how to do this.

I'm building an application with a Laravel 5.1 back-en and a AngularJS frontend. Both are new to me but I love them so far. For my database communication I'm using Propel 2.

So I got my Order object in Laravel set-up with Propel which is working fine. To use this model in Angular I created a resource factory.

angular.module('flex')
    .factory('Order', ['$resource', 'Address', 'Person', function($resource, Address, Person)
    {
        var Order = $resource('/restful/shop/order/:id', {id: '@id'}, {
            query: {
                method: 'GET',
                isArray: true,
                transformResponse: function(data, header)
                {
                    var jsonData = angular.fromJson(data);
                    var orders = [];

                    angular.forEach(jsonData, function(item)
                    {
                        var order = new Order(item);
                        orders.push(order);
                    });

                    return orders;
                }
            },
            update: {
                method: 'PUT',
                params: {id: '@Id'},
            }
        });

        Order.prototype.Person = null;

        Order.prototype.getAddresses = function() {};
        Order.prototype.getOrderProducts = function() {};
        Order.prototype.getPayments = function() {};
        Order.prototype.getPerson = function()
        {
            if (this.Person != null)
                return this.Person;

            var OrderObject = this;
            this.Person = {};

            Person.get({id: this.PersonId}, function (response)
            {
                OrderObject.Person = response;
            });
            return this.Person;
        };
        Order.prototype.getShippingAddress = function() {};

        return Order;
    }])

As you can see this resource has a function getPerson() which loads a person object from another resource factory.

angular.module('flex')
    .factory('Person', function($resource)
    {
        var Person = $resource('/restful/common/person/:id', {id: '@id'}, {
            query: {
                method: 'GET',
                isArray: true,
                transformResponse: function(data, header)
                {
                    var jsonData = angular.fromJson(data);
                    var persons = [];

                    angular.forEach(jsonData, function(item)
                    {
                        var person = new Person(item);
                        persons.push(person);
                    });

                    console.log(persons);

                    return persons;
                }
            }
        });

        return Person;
    })

So far everything works great. I can load and display my orders and load the person object with this and also display the data from this object.

The issue comes when I want to store updates. If I call Order.$update() the put request is made to my Laravel update action.

public function update($id, Request $request)
{
    // Check for orderI
    // Load order
    $order = OrderQuery::create()
        ->findPk($id);

    // Iterate data
    foreach ($request->all() as $key => $value)
    {
        echo 'set' . $key . "\n";
        $order->{'set' . $key}($value);
    }

    // Save object
    $order->save();
}

Here comes the problem. setPerson on the Order objects expects an Person object but an simple object with just parameters is sent. I could just skip input that is not string or integer but what if I updated details in the person too. I'd be nice if the Person would be updated too but I don't know what is the best way to do this.

My options but I'm hoping there is a better way:

  • Write an custom save function on the Angular side
  • Extend the Laravel update action to detect objects


via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire