I am trying to sort an array of objects that comes from the props on a child component.
However, my sort method Throw
s an error. Maybe I am not using the method properly or I can't properly determine the arguments that needs to be passed to it.
What I am trying to do is to sort according to the arguments passed using the click function and calling a method to execute the sort.
The intention here is when I click the arrow on the name, I can then sort it by name, according to the arrow (asc or desc).
This is my component ApplicationsList.vue
<template>
<div class="modal-backdrop">
<div class="modal">
<header class="modal-header">
<slot name="header">
<h3>{{job.name}}</h3>
<button v-if="application.name" type="button" class="btn-close" @click="back">
<i class="fa fa-arrow-left"></i> Back
</button>
<button type="button" class="btn-close" @click="close">
x
</button>
</slot>
</header>
<section class="modal-body">
<div class="row">
<div v-if="!application.name" class=" col-12 applications-list">
<table class="table table-bordered">
<thead>
<tr>
<th>Name
<i @click="changeSort('name', 'desc')" v-if="this.sortBy === 'name' && this.sortDirection === 'asc' " class="fa fa-sort-up"></i>
<i @click="changeSort('name', 'asc')" v-if="this.sortBy === 'name' && this.sortDirection === 'desc' " class="fa fa-sort-down"></i>
</th>
<th>Email <i class="fa fa-unsorted"></i></th>
<th>Date <i class="fa fa-unsorted"></i></th>
</tr>
</thead>
<tbody>
<tr class="application-row" v-for="application in job.applications" :key="application.id" :application="application" @click="getApplication(application)">
<td>{{application.name}}</td>
<td>{{application.email}}</td>
<td>Applied {{moment(application.created_at).fromNow()}}</td>
</tr>
</tbody>
</table>
</div>
<div v-if="application.name" class="col-12 applicant">
<small>Applied {{moment(application.created_at).fromNow()}}</small>
<h4 v-if="application.name">Name</h4><p>{{application.name}}</p>
<h4 v-if="application.email">Email</h4><p>{{application.email}}</p>
<h4 v-if="application.phone">Phone</h4><p>{{application.phone}}</p>
<h4 v-if="application.linkedin">Linkedin</h4><p>{{application.linkedin}}</p>
<h4 v-if="application.cover_letter">Coverletter</h4><p v-html="application.cover_letter"></p>
</div>
</div>
</section>
<footer class="modal-footer">
</footer>
</div>
</div>
</template>
<script>
import moment from 'moment';
export default {
name: 'ApplicationsList',
props:['job'],
data(){
return{
application: {name:'', email: '', created_at:'', phone: '', linkedin: '', cover_letter: ''},
sortBy:'name',
sortDirection:'asc',
}
},
methods:{
moment,
close(){
this.$emit('closeApplicationsRequest');
},
getApplication(application){
this.application = application;
},
back(){
this.application = '';
},
changeSort(sortBy, sortDirection){
return this.job.application.sort((a, b) => a.sortBy - b.sortBy)
}
},
}
</script>
You've got two problems there:
You are using dot notation on your sort function, which means you are trying to access the literal sortBy
property of your objects.
What you want, instead, is bracket notation , which allows you to pass a variable to the accessor and, as such, get a dynamically set property. Eg
const obj = {
prop1: "value"
};
const myProp = "prop1";
obj.myProp; // undefined;
obj[myProp]; // "value"
You are subtracting two strings from one another, which returns NaN
. The sorting function cannot work like this. Instead, the comparison function needs to return either 0, lower than 0, or greater than 0.
function changeSort(sortBy) {
return this.job.application
.sort((a, b) => {
if(a[sortBy] < b[sortBy]) return -1;
if(a[sortBy] > b[sortBy]) return 1;
return 0;
});
}
I see in your code that you want to add a sorting order, but that wasn't implemented in the function. You could either do:
function changeSort(sortBy, sortDirection) {
const alphabeticalApplications = this.job.application
.sort((a, b) => {
if(a[sortBy] < b[sortBy]) return -1;
if(a[sortBy] > b[sortBy]) return 1;
return 0;
});
return sortDirection === "asc" ? alphabeticalApplications
: alphabeticalApplications.reverse();
}
or
function changeSort(sortBy, sortDirection) {
const sortMultiplier = sortDirection === "asc" ? 1 : -1;
return this.job.application
.sort((a, b) => {
if(a[sortBy] < b[sortBy]) return -1 * sortMultiplier;
if(a[sortBy] > b[sortBy]) return 1 * sortMultiplier;
return 0;
});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.