3

I have an Eloquent Model, for which I created a custom toArray()-method, to include fields from a meta table (which I get by using the eloquent-meta plugin):

class User extends Model{
 // ... Other stuff
 public function toArray(){
 return array_merge(parent::toArray(), $this->getAllMeta()->toArray());
 }
}

When I now try to send this model as a JSON response using Response::json(...), I get:

UnexpectedValueException in Response.php line 403: The Response content must be a string or object implementing __toString(), "boolean" given.

I have traced the error to the JsonResponse.setData($data)-method, in which the json_encode-call returns false. The json_last_error()-method returns JSON_ERROR_SYNTAX and the json_last_error_msg()-method returns Syntax error.

Using the debugger I stopped on the line below and evaluated the statement myself. As expected, it does not work, however if I call it like this, it works:

json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR);

This returns the complete, valid JSON that I expect, without any missing or NULL values.

What's even stranger is, if I stop in the toArray()-method and supply the merged array to json_encode, it works fine, even without partial.

Am I overlooking something obvious here??

asked Mar 16, 2015 at 17:16
2
  • So Model already implements JsonSerializable, and the jsonSerialize() is just a simple wrapper around its toArray(). Are you supplying the merged array directly, or are you doing json_encode($mymodel->toArray())? Commented Mar 16, 2015 at 17:28
  • @JoshfromQaribou no, I'm supplying the model directly. The funny part is, that it works fine, if I remove the toArray()-method. Commented Mar 17, 2015 at 7:43

1 Answer 1

2

The problem was with the eloquent-meta plugin I used. Here's the relevant part from my issue:

I traced the error back to the Helpers.maybeDecode($value)-method:

The current implementation tries to parse the value with json_decode($value) and checks, whether that worked, by checking the json_last_error()-function. The problem is, that this doesn't reset the last error.

When the Helpers.maybeDecode($value)-method is called, while Laravel is encoding the model, and the value it tried to decode was not an valid json (for example, a simple string), the error code is set, causing the json_encode()-function to see it and return null. The problem is with the global nature of the error-variable.

My proposed workaround for this is to reset the json_last_error()-function after checking if decoing worked, and the only way I have found to do this is by decoding something valid (even if it's just an empty array).

Here is the Pull Request with the fix.

answered Mar 17, 2015 at 11:22

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.