I am making a dynamic portfolio for myself using VueJS. I created a way to update experiences and order it based on currently ongoing jobs showing first sorted in ascending order meaning a job with start date May 2021 will show first and then March 2021 (both being present). Next, if I set an end date for the job, it should update and place the current jobs in the front which isn't happening.
Algorithm:
newExp() {
this.editableExperience.sort((a,b) => {
a = a.period.split(' - ');
b = b.period.split(' - ');
let aStartDate = a[0];
let aEndDate = a[1];
let bStartDate = b[0];
let bEndDate = b[1];
if (aEndDate == 'Present' && bEndDate == 'Present') {
return new Date(bStartDate) - new Date(aStartDate);
} else if (aEndDate == 'Present') {
return a;
} else if (bEndDate == 'Present') {
return b;
} else {
return new Date(bStartDate) - new Date(aStartDate);
}
})
this.experience = this.editableExperience;
}
editableExperience is an array of experiences: (I have added only required information)
editableExperience = [{period: 'May 2021 - Present'}, {period: 'November 2020 - Present'}, {period: 'January 2021 - March 2021'}, {period: 'March 2018 - July 2020'}]
Exact issue situation:
- Setting the third element to present job brings it to position 2 but giving it an end date again does not send it to position 3 again.
- Setting the last element to present does not bring it in front of the non-present jobs.
CodePudding user response:
Your compare function is returning a string or a number while the compare function should return either 1, 0 or -1 as per the MDN docs.
I have made changes to your code below:
newExp() {
this.editableExperience.sort((a,b) => {
a = a.period.split(' - ');
b = b.period.split(' - ');
let aStartDate = a[0];
let aEndDate = a[1];
let bStartDate = b[0];
let bEndDate = b[1];
if (aEndDate == 'Present' && bEndDate == 'Present') {
return (new Date(bStartDate) - new Date(aStartDate)) > 1 ? 1 : -1;
} else if (aEndDate == 'Present') {
return -1;
} else if (bEndDate == 'Present') {
return 1;
} else {
return (new Date(bStartDate) - new Date(aStartDate)) > 1 ? 1 : -1;
}
});
this.experience = this.editableExperience;
}
CodePudding user response:
The view model is a little bit mixed with data model, I would suggest to keep a clean data model which hold the original values, it is good for processing like sort. then a a computed property as view model which is depend on the data model.
data: () => ({
editableExperience: [
{start: 202105, end: 999999},
{start: 202011, end: 999999},
{start: 202101, end: 202103},
{start: 201803, end: 202107},
],
}),
then the sorting will looks like:
this.editableExperience.sort((a,b) => {
return b['end'] === a['end']? b['start'] - a['start'] : b['end'] - a['end']
})
for your view(display)
computed: {
viewExperiences() {
const ve = []
for(const e of this.editableExperience) {
ve.push(this.getExperienceDisplay(e))
}
return ve
}
},
methods: {
formatExperienceDate(dateInt) {
if(dateInt === 999999) return 'Present'
const dateStr = dateInt.toString()
const date = new Date(dateStr.substring(0, 4) '-' dateStr.substring(4, 6))
return date.toLocaleDateString("en-US", {year: 'numeric', month: 'long'})
},
getExperienceDisplay(exp) {
const startDate = this.formatExperienceDate(exp['start'])
const endDate = this.formatExperienceDate(exp['end'])
return `${startDate} - ${endDate}`
},
}