Search code examples
phplaravellaravel-5eloquent

Laravel Query Builder: How do I sort results by date - first with ascending order by future dates and then by descending order by past dates?


I have a model tasks with complete tasks with datetime in the past and upcoming tasks with datetime in the future.

While retrieving the tasks, I want to display the upcoming tasks arranged in ascending order (from now to the future) and tasks in the past in descending order (from now to the past).

public function getTasks()
{
        $futureTasks = Task::whereDate('datetime', '>', Carbon::now())->orderBy('datetime', 'asc')->get();
        $pastTasks   = Task::whereDate('datetime', '<', Carbon::now())->orderBy('datetime', 'desc')->get();
        $tasks       = array_merge($futureTasks, $pastTasks);
        $response    = ['tasks' => $tasks];
        // return...
}

I'm getting the following error:

array_merge(): Argument #1 is not an array

If I reverse the order of arguments for array_push function, I still get the same error.

 public function getTasks()
{
        $futureTasks = Task::whereDate('datetime', '>', Carbon::now())->orderBy('datetime', 'asc')->get();
        $pastTasks   = Task::whereDate('datetime', '<', Carbon::now())->orderBy('datetime', 'desc')->get();
        $tasks       = array_merge($pastTasks, $futureTasks);
        $response    = ['tasks' => $tasks];
        // return...
}

And If I retrieve only the futureTasks or pastTasks without array_merge, I get the desired output.

public function getTasks()
{
        $futureTasks = Task::whereDate('datetime', '>', Carbon::now())->orderBy('datetime', 'asc')->get();

        $response    = ['tasks' => $futureTasks];
        // return...
}

What am I doing wrong here? Thanks a lot for your time.


Solution

  • Both the results are a collection. You can use the collection merge method.

    public function getTasks()
    {
        $futureTasks = Task::whereDate('datetime', '>', Carbon::now())
            ->orderBy('datetime', 'asc')
            ->get();
    
        $pastTasks = Task::whereDate('datetime', '<', Carbon::now())
            ->orderBy('datetime', 'desc')
            ->get();
    
        $tasks = $futureTasks->merge($pastTasks);
        $response = compact('tasks');
        // return...
    }
    

    Since you're using the whereDate condition, you're missing all the data from the present date based on your queries. You might want to check that.