1

I am using Laravel REST API endpoints to fetch data from a MySQL database. A significant number of cells (let's say 80–90 %) are 'blank' or 'falsy', by which I mean null, empty string, false or 0. I struggle to find a way to filter these data out to save bandwidth (and the overall volume of JSON response).

As I found out from docs and similar questions on this site, I should go for Laravel's collection wrapper and its filter() method. It works perfectly when applied to single row query, like that:

public function getByNumberOfYear($year, $num)
{   
    $contractNumOfYear = Contract::NumberOfYear($year, $num)->first();
    $collection = collect($contractNumOfYear);

    return $collection->filter();
}

But it does't work if naïvely applied on query containing multiple rows (= array of objects in JSON response):

public function showYear($year)
{   
    $contractFromYear = Contract::year($year)->get();
    $collection = collect($contractFromYear);

    return $collection->filter();
}

It doesn't throw an error, but in the resulting array of objects (in JSON) the falsy data persists. What am I missing? I'm mostly a front-end guy and I don't know PHP much. Do I have to loop through the query and then apply filter? Any help would be much appreciated.

HynekS
  • 2,738
  • 1
  • 19
  • 34
  • 1
    Just a note that `->get()` returns a `Collection`; there is no reason to call `collect()` on the result of a `->get()`. Using `->first()` returns a single `Model`, `stdClass` or `null`, so calling `collect()` on that is valid, but could also be accomplished by calling `->get()` instead of `->first()`. – Tim Lewis Nov 21 '18 at 19:19
  • @Tim Thank you for valuable informations. As I already admit, my approach is kind of naïve. Laravel documentation is said to be very good, but I have to say that, for me, there are a lot of not-such-clear parts. – HynekS Nov 21 '18 at 19:24
  • I would say that the documentation is pretty good, but maybe not to for someone somewhat unfamiliar with PHP. And no problem, glad to help. So to clarify, by "empty", do you mean that specific columns are empty? I.e. what is a `Contract`? An eloquent Model referencing your `contracts` table? Could this be accomplished with a series of `whereNotNull("column")` or `where("column", "!=", "")`, (or `false`, `"0"` instead of `""`) etc etc? – Tim Lewis Nov 21 '18 at 19:28
  • @Tim: Yes, exactly, `Contract` is a model for `contracts` table. I was thinking about filtering by SQL first, by that would omit the whole row or column, wouldn't it? I need only to omit 'blank' cells. – HynekS Nov 21 '18 at 19:37
  • @Tim: Strangely, I tried to not explicitly use `collect` method and to use `get()` instead of `first()` – and the filtering stops to work. – HynekS Nov 21 '18 at 19:38
  • Hmm yeah, if you did `->where()` then yes, it would ignore rows. However, `->filter()` is going to do that too; it will only return `items` (a `collection` is a fancy array of `items`, whatever those may be) that pass a given truth test. If you don't want those properties returned in your JSON response, you might need to loop and use `unset()`, something like `foreach($contracts AS $contract){ if($contract->example == false){ unset($contract->example); }}` – Tim Lewis Nov 21 '18 at 19:43
  • Also, maybe this question can help? https://stackoverflow.com/questions/25690999/laravel-remove-null-eloquent-object-attributes-from-json; there's a few articles in the answer that might help. – Tim Lewis Nov 21 '18 at 19:47
  • @Tim: Yes, I've seen that post and those linked suggestions in response, but they were quite overwhelming to me (due to my unfamiliarity with Laravel). But I will give them a second chance. Thank you. – HynekS Nov 21 '18 at 19:54
  • Ah yeah... That's fair. One more thing, if you didn't omit the empty columns, would it be possible for the app consuming the JSON response to omit them/ignore if empty? I.e. do you **need** to filter out on the API end? – Tim Lewis Nov 21 '18 at 20:14
  • 1
    @Tim: These empty values are not problem *per se*, but they bloat up the JSON (as I wrote, probably 75–80 % of its content are property names with empty values). I also intend to cache the response somehow, and, for instance, Local Storage has quite limited size (My 'All Contracts' JSON is 3,5 Mb and it will grow with another contracts being added.) – HynekS Nov 21 '18 at 20:43

0 Answers0