Mongoose data not showing on the web page as expected

36 Views Asked by At

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

0

There are 0 best solutions below