I am creating a web app for keeping notes using mongodb, node.js, express and pug. When I load the home page the notes are arranged in order of date created. When I click the button to arrange the notes in alphabetical order the notes are sorted correctly on the back end but are still displayed in order of date created. My question is how to make the notes displayed in alphabetical order.
My note schema:
const noteSchema = new mongoose.Schema(
{
title: {
type: String,
required: [true, 'You must enter a title.'],
trim: true,
unique: [true, 'A note title must be unique.'],
},
noteText: {
type: String,
trim: true,
},
itemsArr: [
{
type: mongoose.Schema.ObjectId,
ref: 'Item',
},
],
slug: String,
createdAt: {
type: Date,
default: Date.now(),
select: false,
},
user: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: [true, 'A note must belong to a user.'],
},
doneList: [
{
type: mongoose.Schema.ObjectId,
ref: 'Item',
},
],
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
},
)
My backend code (which does return the data alphabetically)
My note route 'router.route('/?sort=title').get(noteController.getAllNotes);'
My APIFeatures
class APIFeatures {
constructor(query, queryString) {
this.query = query;
this.queryString = queryString;
}
filter() {
const queryObj = { ...this.queryString };
const excludeFields = ['page', 'limit', 'sort', 'fields'];
excludeFields.forEach((el) => delete queryObj[el]);
let queryStr = JSON.stringify(queryObj);
queryStr = queryStr.replace(/\b(gt|gte|lt|lte)\b/g, (match) => `$${match}`);
this.query = this.query.find(JSON.parse(queryStr));
return this;
}
sort() {
if (this.queryString.sort) {
const sortBy = this.queryString.sort.split(',').join(' ');
this.query = this.query.sort(sortBy);
} else {
this.query = this.query.sort('createdAt _id');
}
return this;
}
limitFields() {
if (this.queryString.fields) {
const fields = this.queryString.fields.split(',').join(' ');
this.query = this.query.select(fields);
} else {
this.query = this.query.select('-__v');
}
return this;
}
paginate() {
const page = this.queryString.page * 1 || 1;
const limit = this.queryString.limit * 1 || 100;
const skip = (page - 1) * limit;
this.query = this.query.skip(skip).limit(limit);
return this;
}
}
My note controller
exports.getAllNotes = catchAsync(async (req, res, next) => {
const features = new APIFeatures(
Note.findOne({ user: req.user.id }),
req.query,
)
.filter()
.paginate()
.sort()
.limitFields();
const notes = await features.query;
if (notes.length === 0) {
return next(new AppError('No notes for this user were found.', 404));
}
res.status(200).json({
status: 'success',
results: notes.length,
notes,
});
});
When I try to access this data from the web page it returns the data in order of date created.
My frontend code
My view route 'router.get('/sortByTitle', authController.protect, viewController.getHome);'
My view controller
exports.getHome = catchAsync(async (req, res, next) => {
try {
res.status(200).render('home', {
title: 'Home',
date,
today,
});
} catch (error) {
console.log(error);
}
});
My html in pug
extends base
block content
main.main
if user
//- - console.log(user.notes)
.container
h1.title-welcome= `Welcome ${user.name.split(' ')[0]}`
h3.date #{today}
p.display-text Display options:
.display-container
.display
p.text Date Created
p.text Alphabetically
label.switch
input#alpha(type='checkbox')
span.slider.round
button.btn.alpha Alpha
a.btn.add-btn(href='/addNote') Add Note
i.fa-solid.fa-plus
form#search-form
.form-group#search-form-group
label.form-label(for='search-title') Search:
#search-input
input.form-input#search-title(type='text' placeholder='Enter note title...')
button.btn.btn-search(title='Search notes')
i.fa-solid.fa-magnifying-glass
- const noNotes = user.notes.length === 0 ? true : false
if noNotes
.notes-container-example
a.btn#btn-exmaple(href='/exampleNote') Example Note
else
.notes-container
each note in user.notes
a.btn.show-note(id=`${note.id}` )= note.title
else
.container
h1.main-title Note It
i.fa-solid.fa-pen-nib
p.main-text One app for keeping all your notes and lists.
.home-btn-container
a.btn(href='/signup' ) Sign Up
a.btn(href='/login' ) Login
I have tried adding an event listener to the button with the class name of alpha and call a function called sortFunction. This does retrive the data ordered as I want but still does not display it on the web page.
const alphaBtn = document.querySelector('.alpha');
if (alphaBtn) {
alphaBtn.addEventListener('click', (e) => {
e.preventDefault();
sortfunction();
});
}
export const sortfunction = async () => {
try {
const res = await axios('http://127.0.0.1:8080/api/v1/notes/?sort=title');
console.log(res.data);
if (res.data.status === 'success') {
location.assign('/sortByTitle');
}
} catch (error) {
console.log(error);
showAlert(
'error',
'There was an error sorting your notes. Please try again later.',
);
}
};
The above console.log shows the data is being returned in the order I want but I can't figure out why it won't display correctly on the page. I feel that I might have a conflict somewhere in my code. Please, any help will be greatly appreciated.
Thanks