Hi Everyone,
I just added a “liking” feature to my repeater content. It’s virtually the same thing as liking an Instagram or FB post. Only logged in users can like posts, they can add or remove their likes, etc. It works exactly as you probably imagine.
I took somewhat of a unique approach. I created field called “likes” in one of my collections and then track the total likes by storing a JSON with all Member’s ID who has liked the post. I was concerned that parsing and stringifying JSON’s would cause lag time issues, but so far, it is working very well.
Some code experience will be necessary to implement it, but the pieces are effectively below:
//
let likes_array = [];
$w.onReady(function () {
setData();
});
setData() {
// .....Create and populate your repeater. Then within the onItemReady have the following code
// Check if any likes exist, parse the JSON and count how many users have liked each post.
let likes = itemData.likes;
if (likes) {
console.log(likes);
let parsed_likes = JSON.parse(likes);
$w("#likes").text = parsed_likes.length.toLocaleString();
} else {
$w("#likes").text = (0).toLocaleString();
}
// For items that have likes, check to see if the current User was one of the likes, if so make heart full
if (itemData.likes) {
if (itemData.likes.includes(wixUsers.currentUser.id)) {
$w("#emptyHeart").hide();
$w("#emptyHeart").collapse();
$w("#fullHeart").show();
$w("#fullHeart").expand();
}
}
// If a user is not logged in, prompt login before they can like anything
// Each time a heart is "toggled" run function to update collection.
$w("#emptyHeart").onClick( (event) => {
if (wixUsers.currentUser.loggedIn) {
let $item = $w.at(event.context);
// let data_item = itemData;
toggleHeart($item, itemData);
} else {
logIn();
}
} );
$w("#fullHeart").onClick( (event) => {
let $item = $w.at(event.context);
// let data_item =
toggleHeart($item, itemData);
} );
// When empty heart is clicked, make it full and vise versa.
// Update the count by one depending on whether they like or unlike a post.
// Run the final functions which either add or remove a userId from the JSON.
async function toggleHeart(item, itemData) {
let emptyHeart = item("#emptyHeart");
let fullHeart = item("#fullHeart");
let likes = item("#likes");
// toggle the fold at the index
if (fullHeart.collapsed) {
fullHeart.expand();
fullHeart.show();
emptyHeart.collapse();
emptyHeart.hide();
// await fullHeart.disable();
await saveHeart(itemData);
// fullHeart.enable();
likes.text = (Number(likes.text) + 1).toLocaleString();
}
else {
fullHeart.collapse();
fullHeart.hide();
emptyHeart.expand();
emptyHeart.show();
// await emptyHeart.disable();
await deleteHeart(itemData);
// fullHeart.enable();
likes.text = (Number(likes.text) - 1).toLocaleString();
}
}
async function saveHeart(itemData) {
if (!itemData.likes) {
likes_array.push({
"_id": wixUsers.currentUser.id
})
console.log(likes_array);
itemData.likes = await JSON.stringify(likes_array);
wixData.update("Project_Submission", itemData)
.then( (results) => {
});
} else {
likes_array = JSON.parse(itemData.likes);
likes_array.push({
"_id": wixUsers.currentUser.id
})
console.log(likes_array);
itemData.likes = await JSON.stringify(likes_array);
wixData.update("Project_Submission", itemData)
.then( (results) => {
});
}
}
async function deleteHeart(itemData) {
console.log("Delete Heart");
if (itemData.likes) {
let parsed_likes = JSON.parse(itemData.likes);
let deleted_likes = parsed_likes.filter(function( obj ) {
return obj._id !== wixUsers.currentUser.id;
});
console.log(deleted_likes);
itemData.likes = await JSON.stringify(deleted_likes);
wixData.update("Project_Submission", itemData)
.then( (results) => {
// console.log()
});
}
}