HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptvueMinor

Present table of data, acquired from an endpoint, with option to sort by different values

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
endpointpresentwithacquiredoptiondifferentvaluessortfromdata

Problem

I have built a Vue app which fetches data from an endpoint and presents that data in a table with sortable columns.

The app is based on this React challenge which is to create a table of users and their properties, from the data provided in the endpoint.

Here are the user stories fulfilled:

  • I can see a table of the Free Code Camp campers who've earned the most brownie points in the past 30 days.



  • I can see how many brownie points they've earned in the past 30 days, and how many they've earned total.



  • I can toggle between sorting the list by how many brownie points they've earned in the past 30 days and by how many brownie points


they've earned total.

Here is my code (working example):



const endpoint = 'https://fcctop100.herokuapp.com/api/fccusers/top/recent'

const store = {
state: {
sortingBy: ''
}
}

new Vue({
el: '#app',
data() {
return {
data: [],
state: store.state
}
},
mounted() {
Vue.http.get(endpoint).then(response => {
this.data = response.body
}, response => {
console.warn('There was a data error:', response)
})
},
methods: {
sortByRecent() {
this.data = _.sortBy(this.data, 'recent').reverse()
store.state.sortingBy = 'recentDescending'
},
sortByAllTime() {
this.data = _.sortBy(this.data, 'alltime').reverse()
store.state.sortingBy = 'allTimeDescending'
},
getActiveClass(string) {
return {active: store.state.sortingBy.includes(string)}
}
}
})

#app {
display: flex;
flex-direction: column;
align-items: center;
}
.active {
font-weight: bold;
}
button {
font-size: 20px;
}
img {
border-radius: 50%;
height: 30px;
width: 30px;
}



Sort by Recent Points
Sort by All Time Points



#

Username
Recent Points
Total Points



{{index + 1}}



{{user.username}}
{{user.recent}}
{{user.alltime}}



Solution

I'm new to Vue myself so this may not be 100% accurate, just my own opinions. Kudos for learning and reaching out for feedback! You seem to have grokked a lot so I'm impressed.

  • Computed properties are used the same as data properties. You do not call them like methods, and you can't pass parameters to computed properties. Instead of :class="getActiveClass('recent')" you'd have to use something like :class="{active: isSortedByRecentPoints}" or :class="recentPointsHeaderClasses". But what you have works just fine IMO.



  • There is no penalty to importing Vue in multiple places, and it is actually good practice. Think of it like Java imports, you are declaring all of our external dependencies in your header so you know what kinds of operations this code is likely to perform without reading every single line.



  • The correct hook is determined by your use case. For this example any one of the hooks mentioned would work fine. For more general advise, I tend to prefer the mounted hook, but that's just me and I don't know what I don't know. Will the component get mounted multiple times? Will you have all of the data you need to make the call at created? I'm not familiar enough with the details of Vue to give more in depth advise.



  • For this example one Vue instance works just fine. If you want to experiment you can extract a true component from your code and create an API: The table data would be an input prop, and any actions on that data would be output events. I wouldn't consider sorting to be a reasonable output event. How about a view details event on the user?



If you're looking for extra credit I'd recommend looking into Vuex for your store. Currently you're mutating the store directly, which kind of goes against the whole point of using a store. Also a store is overkill for this example, but I'd recommend it for learning purposes. I'll give you a hint: Instead of using state in your data object you will probably want to bind directly to sortingBy and then use $store.commit to alter it in your methods. Commit will trigger a mutation to change the state, which will in turn update your component's data. You can do something similar for the table data - put it in a store and dispatch a fetchdata action to GET your data, then commit it to the state. This may seem like overkill at first (and it probably is for simple apps) until you start playing around with the time travelling debugger in the Vue devtools, hot module replacement, and the like. Super cool stuff.

Context

StackExchange Code Review Q#149593, answer score: 3

Revisions (0)

No revisions yet.