Yii2: Error return when using JSON_FORMAT with NULL value

Created on 5 Sep 2017  路  17Comments  路  Source: yiisoft/yii2

Invoke return $this->asJson(null); in controller
or
$response->format = Response::FORMAT_JSON; $response->data = null;

will output nothing.

In standard json, the null value must be output a 'null' string.
But when I set output format to json, and value is null, it output nothing.
I think the right output is a 'null' string, hope fixed.

good first issue hacktoberfest under discussion bug

Most helpful comment

@cebe I don't think we should modify content directly in Controller::asJson().
The better solution is to change JsonResponseFormatter behavior like this:

protected function formatJson($response)
    {
        if ($response->data !== null) {
            $options = $this->encodeOptions;
            if ($this->prettyPrint) {
                $options |= JSON_PRETTY_PRINT;
            }
            $response->content = Json::encode($response->data, $options);
        } else {
            $response->content = 'null';
        }
    }

All 17 comments

this is expected according to the docs of Response::$data: https://github.com/yiisoft/yii2/blob/9b01ca275f891c245c2e840ed93c87f715c04e70/framework/web/Response.php#L125-L126 what is the use case of returning null from a controller?

@cebe I think that use case is irrelevant here - empty string is invalid JSON. "null response" should return null encoded as JSON.

>> JSON.parse('')
SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
>> JSON.parse('null')
null

https://3v4l.org/R4mRJ

Might this not be a breaking change?

Strict correctness of the JSON encoding isn't necessarily the requirement if Yii, according to its documentation, specifies that a PHP null means "don't output anything". People might be using it.

Hmm... you're right. It may be used.

People might be using it.

For what? Empty JSON is invalid response. You can almost always say "we can not fix this bug, because people may rely on it".

@tom-- But people has use \Yii::$app->response->format = Response::FORMAT_JSON;
That mean wan't output as json format. If output nothing, that format must not be JSON.

What status now? any changes?

the problem here is the duplicate meaning of null, it could be a valid JSON value OR mean that property data should not be converted to populate property content.

To fix this for Controller::asJson() we could add something like

$response->format = Response::FORMAT_JSON;
if ($data === null) {
    $response->data = null;
    $response->content = 'null';
} else {
    $response->data = $data;
}

@cebe I don't think we should modify content directly in Controller::asJson().
The better solution is to change JsonResponseFormatter behavior like this:

protected function formatJson($response)
    {
        if ($response->data !== null) {
            $options = $this->encodeOptions;
            if ($this->prettyPrint) {
                $options |= JSON_PRETTY_PRINT;
            }
            $response->content = Json::encode($response->data, $options);
        } else {
            $response->content = 'null';
        }
    }

I'm ready to make PR with this change and updated tests

Please do.

I'm using json format for my REST API. After your breaking changes I'm receiving 'null' as response' body for endpoint requested with method OPTIONS instead of empty output.

@beatep please report as issue at github.

That was already reported in #17111, I just saw.

Was this page helpful?
0 / 5 - 0 ratings