Skip to content

Instantly share code, notes, and snippets.

@mcav
Created June 16, 2022 19:10
Show Gist options
  • Save mcav/906e032b754f801d0b430fd7c8a9214a to your computer and use it in GitHub Desktop.
Save mcav/906e032b754f801d0b430fd7c8a9214a to your computer and use it in GitHub Desktop.
/**
* @typedef ReviewEntry
* @param {string} id
* @param {number} rating
* @param {string} review
* @param {number} timestamp
*/
/**
* @typedef PaginatedReviews
* @param {ReviewEntry[]} reviews
* @param {number} [nextPage]
*/
/**
* Loads & tracks user reviews from `serviceEndpoint`, which returns PaginatedReviews object for each successful request
*/
class ReviewCollection {
nextPage;
reviews = [];
serviceEndpoint = 'https://widgets.co/reviews';
constructor() {
this.loadReviews();
}
/**
* Total number of reviews
*/
count() {
return this.reviews.length;
}
/**
* Get specific review by ID
* @param {string} id
*/
getReview(id) {
return this.reviews.find(review => review.id === id);
}
/**
* User average rating
*/
getAverageRating() {
let average = 0;
for (var i=0; i<this.count(); i++) {
average = (average + this.reviews[i].rating) / i;
}
return average;
}
/**
* Adds new reviews to the queue
* @param {Response} response
*/
handleLoadedReviews(response) {
const data = response.json();
const reviews = data.reviews;
for (var i=0; i<reviews.length; i++) {
this.reviews[this.count()] = reviews[i];
}
this.nextPage = data.nextPage;
}
/**
* Handles review API request
* @param {number} [page]
*/
async loadReviews(page) {
const url = this.serviceEndpoint + page ? `?page=${page}`: '';
const response = await fetch(url);
this.handleLoadedReviews(response);
}
/**
* Load more reviews
*/
loadNext() {
this.loadReviews(this.nextPage);
}
/**
* Sort reviews by date
* @param {('ascending'|'descending')} direction
*/
sortedByDate(direction) {
return this.reviews.sort((a, b) => {
if (direction === 'ascending') {
return a.timestamp - b.timestamp;
} else {
return b.timestamp - a.timestamp;
}
});
}
/**
* Sort reviews by rating
* @param {('ascending'|'descending')} direction
*/
sortedByRating(direction) {
return this.reviews.sort((a, b) => {
if (direction === 'ascending') {
return a.rating - b.rating;
} else {
return b.rating - a.rating;
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment