Building a like/dislike feature in Angular

Here is a snippet of code I have that includes like and dislike buttons with font-awesome icons:

<ng-container *ngFor="let answer of question.answers">
    <p class="answers">{{answer.text}} <i class="fa fa-hand-o-left" (click)="likeDislike($event,answer.id,'fa-thumbs-up')"></i></p>
  </ng-container>

Additionally, there is a function:

likeDislike(event: any, answerId: string, haveClass: string) {
    const hasClass = event.target.classList.contains(haveClass);
    if (hasClass) {
      this.renderer.removeClass(event.target, 'fa-thumbs-up');
      this.renderer.addClass(event.target, 'fa-thumbs-down');
    } else {
      this.renderer.removeClass(event.target, 'fa-thumbs-down');
      this.renderer.addClass(event.target, 'fa-thumbs-up');
    }
  }

I feel like this code could be improved by creating a directive. Can someone assist me with that?

Answer №1

You might consider placing it within a Component for added functionality with two-way binding.

Experience the feature in action

Take a look at this live demo on StackBlitz.

Implementation example

<app-fa-like [(liked)]='liked'></app-fa-like>

Component implementation

Please note: The styles and __ are included here for demonstration purposes only. Your app's Font Awesome integration should handle these aspects.

import {Component, Input, Output, EventEmitter} from '@angular/core';

@Component({
  selector: 'app-fa-like',
  template: `
    <i 
      class='fa'
      [class.fa-thumbs-up]='liked'
      [class.fa-thumbs-down]='!liked'
      (click)='toggle()'
    >__</i>`,
  styles: [`
  .fa.fa-thumbs-up{background: green;}
  .fa.fa-thumbs-down{background: red;}
  `]
})
export class LikeComponent{
  @Input('liked') liked = true;
  @Output() likedChange: EventEmitter<boolean> = new EventEmitter();
  toggle(): void {
    this.liked = !this.liked;
    this.likedChange.emit(this.liked);
  }
}

Answer №2

When working with Angular, the possibilities are endless. It's hard to say if one option is superior to another. Here are a few suggestions:

  1. Utilize ngClass

  2. Implement *ngIf

  3. Try using an Angular variable. Something along these lines should do the trick:

    <i class="fa {{answer.faFont}}" (click)="toggleIcon(answer)"></I>
    
    toggleIcon(answer:any) {
      answer.faFontFlg = !answer.faFontFlg;
      answer.faFont = (answer.faFontFlg)?'fa-thumbs-up':'fa-thumbs-down';
    }
    

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can the chosen date in a calendar date picker be linked to a variable that is accessible to a separate file?

Currently, I am developing a React application and have integrated a date picker feature using Ant Design to enable users to select a date range. My goal is to store the selected date value into a variable that can be accessed by another file in my progr ...

Using a key as an argument in the `map` function invocation

I keep getting a warning message stating that each child in the array does not have a unique key. const ITEMS = [ { "name": "apple", displayName: "Apple" "name": "orange", displayName: "Orange" }, { "name": "banana", di ...

Nested tables in Datatables retrieving child table rows based on parent table

I have been struggling for the past three days to get my nested Datatables working properly. I have a parent table called MAINtable and a child table called adjlinesTable. The issue I am facing is that all lines from the adjlinesTable are being drawn to ...

implementing CORS on an Express server for a specific domain

I am attempting to send a cookie post-login via AJAX from my localhost to a server that is hosted elsewhere. In order to prevent any errors related to cookies, I have included the following code in my Axios setup: var instance = axios.create({ withCr ...

What is the best way to activate a click event when I set a radio button to checked?

I am facing an issue with an uninitialized property in my app.component.ts: color!:string; I am trying to automatically initialize the color property when a radio button is selected: <div> <input type="radio" name="colors" ( ...

The never-ending cycle of an Angular dropdown linked to a function being repeatedly invoked

I am currently working with a PrimeNg dropdown that is fetching its options through a function call. However, I have noticed that this function is being called an excessive number of times. Could this potentially impact the performance or any other aspect? ...

Obtain the VW/VH coordinates from an onclick action in JavaScript

With this code snippet, you'll be able to retrieve the x and y coordinates of a click in pixels: document.getElementById("game").addEventListener("click", function(event) { console.log(event.clientX, event.clientY); }); However ...

gathering identical objects in the collection

I need to calculate the total time of the specified objects and display it in a single list. Here is the object data: var list = [ { 'user': 'Tom', time: 270547 }, { 'user': 'Alex', time: 82081 }, { 'user&apo ...

Why does Array Object sorting fail to handle large amounts of data in Javascript?

Encountered an issue today, not sure if it's a coding problem or a bug in Javascript. Attempting to sort an object array structured like this: const array = [{ text: 'one', count: 5 }, { text: 'two', count: 5 }, { text: 'thre ...

Retrieve data by sorting based on the count column in a joined table with Sequelize

I've been struggling to make this work for some time and was hoping for some guidance. OBJECTIVE: I'm attempting to sort the posts by the number of likes they currently have. CURRENT: const posts = await db.post.findAll({ include: [ db.user ...

"Optimizing Angular (v4+) for Peak Performance: Expert Strategies and

Currently delving into Angular JS, I've kicked off an Angular Project through the Angular CLI with the core version standing at 5.1.0. Seeking guidance on best practices when it comes to crafting a stellar UI. Your insights and tips on the matter wou ...

What is the best way to specify a function type that takes an argument of type T and returns void?

I am in search of a way to create a type that can accept any (x: T) => void function: let a: MyType; a = (x: number) => {}; // (x: number) => void a = (x: string) => {}; // (x: string) => void a = (x: SomeInterface) => {}; / ...

Discover the location of the class definition in VSCode with this helpful clue

Here is the code snippet I am working with: const Gatherer = require('../gatherer'); class MetaRobots extends Gatherer { /** * @param {{driver: !Driver}} options Run options … } module.exports = MetaRobots; When using VSCode, Driver ...

Angular displaying an Object result in place of data

I have been struggling to showcase the json result I receive from my backend on my Angular front-end. Unfortunately, I am facing challenges in displaying this json data fully as it contains characters like . and -. Currently, although I can display the nam ...

Tap to smoothly scroll through each block using the animate() function

ul { padding: 0; margin: 0; height: 180px; overflow: auto; } li { height: 50px; background: pink; list-style: none; margin-bottom: 10px; height: 50px; ...

Mastering typing properties in React with TypeScript

Could someone please help me with this issue? I have created a basic react component. interface iRowData{ name: string } export default function ResultsSection(data: iRowData[]) { return <div>Results</div> } When I try to use it in ano ...

The anchor tag fails to trigger the onClick function in React

I'm having trouble updating the component state in my React app when clicking on an anchor tag within the render method. I've attempted to bind the function in the constructor, but the console.log statement is still not being called. Here's ...

Hover over the text to disable the input element and display it as a textbox

Currently, I have a situation where I have two text boxes - when text is entered into textbox1, textbox2 becomes disabled as expected. However, my second requirement is that upon disabling textbox2, hovering over it should display the message "You can ente ...

Leveraging Next.js for "client-side rendering" in React Encapsulations

My dilemma involves a component housing content crucial for SEO optimization. Here is an excerpt from my code: <AnimatedElement className="flex flex-col justify-start items-center gap-4 w-full" duration={500}> <h2 class ...

I could really use some guidance on how to begin with the Node.JS app file in BlueMix

After delving into JS tutorials, I feel comfortable with the syntax and approach. Now, my focus is on utilizing Node.JS to develop an app using BlueMix. While I consider myself proficient in Java, web programming is uncharted territory for me, leaving me s ...