I have Nuxt.js Hackernews project.
When I get posts from API of Hackernews I do not get sorted posts by time desc.
I need to sort posts by time desc (newer ones first).
/pages/index.vue
<template>
<div>
<button @click="reNew" class="btn"> Force update </button>
<div class="grid grid-cols-4 gap-5">
<div v-for="s in stories" :key="story">
<StoryCard :story="s"/>
</div>
</div>
</div>
</template>
<script>
definePageMeta({
layout: "stories"
})
export default {
data () {
return {
err: '',
stories: [],
interval:null,
}
},
methods: {
async reNew() {
await $fetch('https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty')
.then((response) => {
let results = response.slice(0, 10)
results.forEach(id => {
$fetch('https://hacker-news.firebaseio.com/v0/item/'+ id +'.json?print=pretty')
.then((response) => {
this.stories.push(response)
})
.catch(err=> {
this.err = err
})
})
})
}
},
mounted() {
this.reNew()
},
created(){
this.interval = setInterval(() =>{
this.mounted()},5000)
},
destroyed(){
clearInterval(this.interval)
}
}
</script>
<style scoped>
.router-link-exact-active{
color:#12b488;
}
</style>
You can look at my code in
components/StoryCard.vue below:
<template>
<div>
<div class="card text-center">
<h2><strong>Title: </strong>{{story.title}}</h2>
<p><strong>Score: </strong>{{story.score}}</p>
<p><strong>Author: </strong>{{story.by}}</p>
<p><strong>Date: </strong>{{ new Date(story.time*1000) }}</p>
<NuxtLink :to="`/${story.id}`">
<p class="btn my-4">View details</p> </NuxtLink>
</div>
</div>
</template>
<script setup>
const { story } = defineProps(['story'])
</script>
<style scoped>
.thumb {
max-height: 120px;
max-width: 70%;
margin: 0 auto;
}
</style>
How can I sort posts by time desc (newer ones first)?
How can I do that here using Javascript?
The API that you're using is indeed the official one (listed at the bottom of the official HN page).
Unfortunately, there is nothing integrated regarding any kind of sort via the API itself.
You will need to use the
.sortmethod to run on each object'sdateor similar field.If we take that given URL with all the current posts: https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty
We can see that each one of them is ordered based on upvotes. Hence, the array that you're receiving is full of objects like that one.
Once you have your huge array (in your
storiesstate), it's a matter of running.sorton thetimefield which is nothing more than a UNIX timestamp.So given the following subset of data (as a super simplified example)
you can run the following to have them sorted by "freshest" first
gives the following
The rest of the work is a matter of properly organizing your data and looping on it in your Vue code.
It may be quite un-efficient because it's a huge array (could use a backend middleware server to help the performance). Of course, a native API thing would be the best but I think that it's made on purpose (and hence will never come live).
Update
This is how you would sort the sorties depending on their time, regarding the starting point of my previous answer.