retrieve a declaration from service to displays it into component

Issue

I want my likes counter to be handle in my post.service component, so I ‘ve declared postLoveIts in the field of my class post.service component but I don’t know how to retrieve it in my post-list.component and displays it in my the post-list.component template… thank you for your help !

post.service.ts:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Post } from '../models/post.model';

@Injectable()
export class PostsService {
  
  postLoveIts : number = 0 ;

  private posts : Post[] = [
    {
          title: "Cuite mémorable avec mes friends",  
          content: "lorem ipsum",  
    }
  ];
  postsSubject = new Subject<any[]>();

  emitPosts() {
      this.postsSubject.next(this.posts);
    }

  
  createNewPost(newPost : Post) {
    this.posts.push(newPost);
    this.emitPosts();
  }

  removePost(post : Post) {
    const postIndexToRemove = this.posts.findIndex(
      (postEl) => {
        if(postEl === post) {
          return true;
        } else {
          return ' '
        }
      }
    );
    this.posts.splice(postIndexToRemove, 1);
    this.emitPosts();
  }



  addOne() {
    this.postLoveIts = this.postLoveIts + 1;
    console.log("like(s) :" + this.postLoveIts);
  }


  subtractOne() {
    this.postLoveIts = this.postLoveIts -1;
    console.log("like(s) :" + this.postLoveIts);
  }

post-list.component.ts :

import { Component, OnInit, Input, Output, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { Post } from '../models/post.model';
import { PostsService } from '../services/posts.service';


@Component({
  selector: 'app-post-list',
  templateUrl: './post-list.component.html',
  styleUrls: ['./post-list.component.scss']
})
export class PostListComponent implements OnInit, OnDestroy {
  

  posts : Post[];
  postsSubscription: Subscription;
  postLoveIts : number = 0 ;

  constructor(private postsService: PostsService,
              private router: Router) { }

  ngOnInit(): void {
    this.postsSubscription = this.postsService.postsSubject.subscribe(
      (posts: Post[]) => {
        this.posts = posts;
      }
    );
    this.postsService.emitPosts()
  }

  onAddOne() {
    this.postsService.addOne();
  }


  onSubtractOne() {
    this.postsService.subtractOne()
  }

  onDeletePost(post: Post) {
    this.postsService.removePost(post);
  }

  ngOnDestroy() {
    this.postsSubscription.unsubscribe();
  }
}

and post-list.component.html:


      <ul class="list-group">
            <li class="list-group-item" *ngFor="let post of posts">
                  <h3> {{ post.title }} </h3>
                  <p>  {{ post.content }} </p>
                  <p> {{ postLoveIts }} </p>   

                  <div class="container">
                        <button class="btn btn-success pull-left" (click)="onAddOne()"> J'aime </button>
                        <button class="btn btn-danger pull-left" (click)="onSubtractOne()"> J'aime pas </button>
                  
                  
                        <div class="col-md-10">
                              <button type="button" class="btn btn-primary pull-right" 
                              (click)="onDeletePost(post)"> Supprimer </button>
                        </div>
                  </div>
            </li>
      </ul>


Solution

Create Subject to emit changes of postLoveIts in your service and then subscribe to this Subject in your component, in the subscription you can simply update value of your postLoveIts field in the component.

Something like this (I skipped your code for the sake of readability but I’m assuming it’s there):

export class PostsService {
  
  private postLoveIts$: Subject<number> = new Subject<number>();

  private emitUpdatedPostLoveIts(): void {
    this.postLoveIts$.next(this.postLoveIts);
  }

  watchPostLoveIts(): Observable<number> {
    return this.postLoveIts$.asObservable();
  }

  // below methods already exist in your code but I added one line to each of them
  addOne() {
    this.postLoveIts = this.postLoveIts + 1;
    console.log("like(s) :" + this.postLoveIts);
    emitUpdatedPostLoveIts(); // <- this is new line in this method
  }


  subtractOne() {
    this.postLoveIts = this.postLoveIts -1;
    console.log("like(s) :" + this.postLoveIts);
    emitUpdatedPostLoveIts(); // <- this is new line in this method
  }
}

and then just observe those changes of postLoveIts in the component:

export class PostListComponent implements OnInit, OnDestroy {
  
  ngOnInit(): void {
    this.postsSubscription = this.postsService.postsSubject.subscribe(
      (posts: Post[]) => {
        this.posts = posts;
      }
    );
    this.postsService.emitPosts()

    this.postsService.watchPostLoveIts().subscribe(postLoveIts => {
      this.postLoveIts = postLoveIts;
    });
  }
}

Answered By – Pawel Woroniecki

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published