Sys32's avatar
Level 3

Return array of objects via ajax results in empty response

I am working on a new cart system, and I have a item object and a config object.

The ajax response should return an $items array, and the items array holds the following

private $product; //Product var, storing the Product model.

private $options = []; //Array of option objects.

The request has this at the bottom

return response()->json([ 'items' => $items, ], 200);

Sadly the response is empty in the view.

{"items":[{}]}

0 likes
21 replies
rumm.an's avatar

What is stored in $items array? Where does that array comes from?

before return statement use dd($items); What is the output?

Sys32's avatar
Level 3

The items array stores info about the item itself, Options will hold an array of Option objects.

The item is generated based on user info from an ajax request. This is the output.

array:1 [
  0 => Item {#558
    -product: Product {#564
      +id: 26
      +name: "Example product"
      +description: "Servers"
      +paytype: "one-time"
      +enablestock: 0
      +stock: 0
    }
    -options: []
    -billingcycle: "one-time"
    -parent: null
    -children: []
    -currency: null
    -price: 0.0
    -setup: 0.0
  }
]
rumm.an's avatar

Try this. And let me know if that works.

 return $items;

Laravel automatically converts that into a json response.

rumm.an's avatar

try manually genearating a json response like this:

return response()->json(json_encode($items));
Sys32's avatar
Level 3

This is returned

"[{}]"

All json encoding did was add quotes.

Its as if it's gone. Its weird.

rumm.an's avatar

Yea thats wierd. Can you show me how you generate $items array?

Sys32's avatar
Level 3

This is the item creation, it gets added to the items array like so : $items[] = $item;

Below are the methods of cart item, and the product object for storing it. I made a new product object, instead of using the model directly. That is the product class.

$item = new CartItem();
    $item->setProduct($addonData['productid']);
    $item->setBillingcycle($addonData['billingcycle']);

public function setProduct($productID) {
    $product = BillingProduct::find($productID);

    if (!$product) {
        throw new Exception("The product does not exist.", 400);
    }

    //Create new product object
    $newProduct = new CartProduct($product);

    $this->product = $newProduct;

    return $this->product;
}


class Product
{
    public $id;
    public $name;
    public $description;
    public $paytype;
    public $enablestock;
    public $stock;
    public $enabledcycles;

    function __construct(BillingProduct $product)
    {
        $this->id = $product->id;
        $this->name = $product->name;
        $this->description = $product->description;
        $this->paytype = $product->paytype;
        $this->enablestock = $product->enablestock;
        $this->stock = $product->stock;
        $this->enabledcycles = $product->enabledcycles;
    }
}
rumm.an's avatar

I guess you dont need to make these custom classes model class works fine with Json, If you face problems like relationship loading, you can do eager loading.

Sys32's avatar
Level 3

I recreate them because my cart will be sent to the user with ajax, and I dont want to include everything in the model.

rumm.an's avatar

@N3 If you want to hide some attributes from JSON you can use a protected variable $hiddenin you model class. Like so:

//In Products.php
//Say I want to avoid sending some fields : 'foo' and 'bar'
protected $hidden = [ 'foo', 'bar' ];

In the same way You can hide attributes from any of your models. And Laravel will not serialize them into JSON.

Since the Custom classses you have used are not serializable into JSON. So they cant be converted to JSON.

Sys32's avatar
Level 3

I am well aware of the hidden variable, however the model has many things that shouldnt be sent to the user.

In any case, as soon as I tried the eager loading, that broke sending model too. As soon as I nest objects in objects, it breaks.

rumm.an's avatar

If you are sending JSON response then hidden fields will not be sent to the user.

Sys32's avatar
Level 3

Well in any case, as soon as I tried the eager loading, that broke sending model too. As soon as I nest objects in objects, it breaks.

rumm.an's avatar

Well, Your custom class is not serializable so it is not converted to JSON. The other way is to create php associative array of your custom attributes and return it like so:

$item = [
    'product' => [
      'id'=> 26
      'name'=> "Example product"
      'description'=> "Servers"
      'paytype'=> "one-time"
      'enablestock'=> 0
      'stock'=> 0
    ],
    'options'=> [],
];
$items = [$item];
return $items;

Try generating something like this. This might help.

rumm.an's avatar

Well in any case, as soon as I tried the eager loading, that broke sending model too. As soon as I nest objects in objects, it breaks.

What do you mean when you say 'broken sending Model'

Sys32's avatar
Level 3

When I do

$product = Product::find(1);
return response()->json($product);

It works, I get the product object. But when I do

$product = Product::find(1)->with('Category');
return response()->json($product);

It no longer works, it returns nothing after this. See below

{}
Sys32's avatar
Sys32
OP
Best Answer
Level 3

I ended up just generating an array of the objects to be returned, not sure why ajax freaks out about using objects.

So I added a simple toArray method in the item class.

rumm.an's avatar

@N3 take a look at this:

$product = Product::find(1)->with('Category');
return response()->json($product);

Your $product variable here, has QueryBuilder Instance I guess. This works:

$product = Product::where('id', 1)->with('Category')->first();
return response()->json($product);
Sys32's avatar
Level 3

Maybe, but still doesn't resolve my other issue sadly. Thanks for trying.

sotekno's avatar

I would recommend you to use league/fractal package. It provides you with a way of defining your own "Transformer" classes. This clases will transform you object representation to an array/json, which you can use to generate the ouput.

It also allows you to define complex object hierarchies with nested objects.

Please or to participate in this conversation.