Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

kendrick's avatar

Order paths by date and time, in component

Currently I am order paths by the date record on a path. A path also has a time record on its Model, which means I need to expand my working computation not just only to date but also time (asc).

computed: {
        orderedPaths: function () {
            return _.orderBy(this.paths ? this.paths : [], 'date', 'asc')
        }
},

How can I order it to first orderBy date, then by time? So that 10:00:00 won't be listed after 12:00:00 on the same day?

0 likes
40 replies
bugsysha's avatar

I've never tried multiple field order outside databases. Have you tried doing it through query?

kendrick's avatar

I've never tried multiple field order outside databases

Hey @bugsysha , what do you mean with outside the database?

How would it look like through a query? We would merge date and time and then order it by this query? ->format('Y-m-d H:i:s')

bugsysha's avatar
->orderBy('name_of_the_date_column')
->orderBy('name_of_the_time_column');
kendrick's avatar

Yes that one would easily work through the Controller, but I am ordering the paths within the component.

computed: {
        orderedPaths: function () {
            return _.orderBy(this.paths ? this.paths : [], 'date', 'asc')->orderBy(this.paths ? this.paths : [], 'time', 'asc')
        }
},

// gives me an error while compiling (Unexpected token on the arrow (->))
bugsysha's avatar

-> is for PHP and not for JavaScript. What I've suggested is for PHP/Laravel.

1 like
kendrick's avatar

Could I create somehow a new merged column on the Model (Path.php), where I concatenate date and time as a DateTime string, and then check on it within the computation?

bugsysha's avatar

Could I create somehow a new merged column on the Model (Path.php), where I concatenate date and time as a DateTime string, and then check on it within the computation?

You could but there is no need cause if you go with Laravel then use database feature for that.

Javascript would look something like

return this.paths.sort((a, b) => {
    return a.date - b.date || a.time - b.time;
});
bugsysha's avatar

Also note that this will change the order in your this.paths permanently. If you want to go with nondestructive approach then you can use

return [...this.paths].sort((a, b) => {
    return a.date - b.date || a.time - b.time;
});
bugsysha's avatar

Reason why I do not like sorting in JavaScript is that

[7,1,10,20].sort()

will return

[1,10,20,7]
kendrick's avatar

Thank you @bugsysha

But I am already passing this.paths to the Component as data(), then I compute them and show them within the component view.

Component

<template>

<div v-for="path in orderedPaths">
... show information, in ordered computation 
</div>

</template>
data() {
        return {  
            path: null,
            paths: this.session.paths ? this.session.paths : [],  
        }
    },
computed: {
        orderedPaths: function () {
            return _.orderBy(this.paths ? this.paths : [], 'date', 'asc')
        }
},

bugsysha's avatar

Why do you need paths and orderedPaths especially considering that you are getting paths from this.session?

kendrick's avatar

To order all the paths based on the date, within the component. This is a component, where I can create paths, which will be entered to the v-for loop, ordered by the date. Therefore I am getting all paths from the Session Model, and then push the newly created path to the view.

This won't order the paths in real time, but after a refresh this.paths is then ordered.

bugsysha's avatar

But you can access directly this.session.paths from orderedPaths? So no need for either paths. Right?

Also I'm bit lost why none of my suggestions work?

kendrick's avatar

Sorry for the confusion @bugsysha

paths_table has id, path, date, time

Currently I get all paths correctly ordered by date through


view:

<path-component :session="{{$session}}"></path-component>

component:

computed: {
        orderedPaths: function () {
            return _.orderBy(this.paths ? this.paths : [], 'date', 'asc')
        }
},

I just wanted to add an additional orderBy for the time to my orderedPaths computation.

Tomorrow I have to rethink the Component. One for the creations of paths and one where I get all paths through a PathResource. Currently I am failing to trigger eloquent relationships within the vue component.

bugsysha's avatar

I still do not see a reason why this wouldn't work?

computed: {
    orderedPaths: function () {
        return [...this.paths].sort((a, b) => a.date - b.date || a.time - b.time);
    }
},
kendrick's avatar

Reason why I do not like sorting in JavaScript is that

It works, I have just tried it, but the reason why you don't like it, is true. The order behavior is weird.

kendrick's avatar

Thank you @bugsysha

It works, but as you mentioned [7,1,10,20].sort() will return [1,10,20,7]

bugsysha's avatar

Now when I think about this did you maybe wanted something like this

return [...this.paths].sort((a, b) => `${a.date} ${a.time}` - `${b.date} ${b.time}`);
kendrick's avatar

I tried it, and it returns

 Error in render: "TypeError: Invalid attempt to spread non-iterable instance"

but I think this one makes more sense. Basically, if I have paths like:

2020-01-22, 12:00 // if this has been created before the one below, it will still be in front of the one below, even though 10:00 is less than 12:00

2020-01-22, 10:00

bugsysha's avatar

It is saying that this.paths is not an array. Have you changed that part? If it is changed you can paste here all related changes in the component.

kendrick's avatar

No changes to this.paths

data() {
        return {  
            path: null,
            paths: this.session.paths ? this.session.paths : [],  
        }
    },
bugsysha's avatar

Seems like there maybe some point in the lifecycle of this component where this.paths is not an array.

If this works

return [...this.paths].sort((a, b) => a.date - b.date || a.time - b.time);

then this should work also

return [...this.paths].sort((a, b) => `${a.date} ${a.time}` - `${b.date} ${b.time}`);
kendrick's avatar

return [...this.paths].sort((a, b) => a.date - b.date || a.time - b.time);

Now I get the same error for the first line, weird

bugsysha's avatar

Try this

return [...this.paths].sort((a, b) => {
    return `${a.date} ${a.time}` - `${b.date} ${b.time}`;
});
1 like
bugsysha's avatar

If the template string is not working then

return [...this.paths].sort((a, b) => {
    return a.date + ' ' + a.time - b.date + ' ' + b.time;
});

or even back

return [...this.paths].sort(function(a, b) {
    return a.date + ' ' + a.time - b.date + ' ' + b.time;
});

... spread should work since you've marked answer with it as best.

1 like
kendrick's avatar

It works, sorry for the confusion, I had a typo.

But the orderedPaths, are now just ordered by created_at. Didn't recognize it first, sorry.

bugsysha's avatar

It works, sorry for the confusion, I had a typo.

No problem.

But the orderedPaths, are now just ordered by created_at. Didn't recognize it first, sorry.

So you are saying that after all current "best answer" is the correct logic you need?

kendrick's avatar

So you are saying that after all current "best answer" is the correct logic you need?

No @bugsysha , as the paths are now ordered in the way I created them, so basically triggering the created_at somehow, id 1, id 2, id 3, instead of getting the date and time record of a path, to order the paths.

Next

Please or to participate in this conversation.