You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
Contents
Recent Posts
- Object Oriented Programming With TypeScript
- Angular Elements Advanced Techniques
- TypeScript - the Basics
- The Real State of JavaScript 2018
- Cloud Scheduler for Firebase Functions
- Testing Firestore Security Rules With the Emulator
- How to Use Git and Github
- Infinite Virtual Scroll With the Angular CDK
- Build a Group Chat With Firestore
- Async Await Pro Tips
Facebook-Inspired Reactions From Scratch With Angular and Firebase
Episode 21 written by Jeff DelaneyIn this lesson, we are going to build a Facebook-inspired reaction component. It works by mapping each reaction type to an integer then saves it with an associated userId. This is similar to the reddit voting system lesson, with some added complexity to manage the various reaction types.
Importing the Graphics
First, let’s add some graphics to the assets folder. I’m using Icon Finder to download free replicas of the Facebook UI in SVG format.
In this tutorial, I am going to add them to src/assets/reactions/
, but you might consider hardcoding them as Base64 strings because they are very small images.
Mapping the Emoji Graphics to Integers
For the sake of simplicity, let’s map the emojis to integers. A user can only have one reaction per item. To avoid mixing up the index of each reaction emoji, we will define them in an array.
emojiList = ['like', 'love', 'wow', 'haha', 'sad', 'angry'] |
Now each emoji name is connected to an integer index, like-0
, love-1
, wow-2
, etc.
Data Modeling
In the database, the the userId
will be the key and the index integer will be the value for keeping track of reactions, with each key-value pair nested under the corresponding itemId
.
reactions |
Reactions Service
The reactions service needs to grab the current reactions for an item, then give the user functions to update/remove them. I am also defining a couple utility functions to handle the sorting/counting reactions when they are emitted from an observable.
reaction.service.ts
import { Injectable } from '@angular/core'; |
countReactions()
takes advantage of Lodash to group the reactions by their value, then count the length of entries, returning an object that looks like this:
{ |
userReaction()
simply checks to see if the user’s ID is present in the reactions and returns its value.
Reactions Component
The component will subscribe to the reactions as a FirebaseObjectObservable
, then map them to an object of counts and determine the current user’s reaction.
react()
will see if the users’s vote matches the current reaction and remove it if true. If false, it will update the user’s reaction to this new value.
reaction.component.ts
import { Component, OnInit, Input, OnDestroy } from '@angular/core'; |
First, there needs to be some type of parent component that can be reacted to, whose $key
gets passed to the child.
reaction.component.html
<reaction [itemId]="item.$key"></reaction> |
The component HTML will display the reaction options in a tooltip, just like Facebook. A showEmojis
boolean variable is toggled with the mouseenter
and mouseleave
events.
From there, we loop over the the emojis, using *ngFor
to extract both the value and the index of the array. Each emoji will trigger the react(i)
function with its index number on click.
Next, we replicate the like text button and notice userReaction != null
. This statement is used because 0 will evaluate to false, which corresponds to the like action.
Lastly, We loop over the emojis again, this time using the reactionCount
to show the number reactions for each type.
<div class="wrapper" (mouseenter)="toggleShow(true)" (mouseleave)="toggleShow(false)"> |
SCSS Styles
Here is the SCSS used in this lesson. It’s just a rough start, but I wanted to include include it for completeness.
.wrapper { |
That’s it for Facebook-inspired reactions. Let me know what you think in the comments.