Angular subject next not triggering subscribe

847 views Asked by At

I searched here for answer but can't figure out why i'm facing this issue.

I have no errors on my console.

I want to emit a new value over a subject with its next method from a service. Then, in the component that use this service, I'm subscribing to the subject.

The service does those : set, add, delete and update recipe object in an array.

My service code :

@Injectable({
  providedIn: "root",
})
export class RecipesServices {
  recipesChangeSubject: Subject<Recipe[]> = new Subject<Recipe[]>();
  private _recipes: Recipe[] = RECIPES;

  constructor(private errorsService: ErrorsService, private router: Router) {}

  setRecipesFromFetch(recipesFromFetch: Recipe[]) {
    this._recipes.length = 0;
    for (let recipe of recipesFromFetch) {
      this._recipes.push(recipe);
    }
    this.recipesChangeSubject.next([...this._recipes]);
  }

  addRecipe(recipe: Recipe) {
    this._recipes.push(recipe);
    this.recipesChangeSubject.next([...this._recipes]);
  }

And my component code :

import { Component, OnInit } from "@angular/core";
import { Subscription } from "rxjs";
import { Recipe } from "../recipe.model";
import { RecipesServices } from "../recipes.service";

@Component({
  selector: "app-recipes-list",
  templateUrl: "./recipes-list.component.html",
  styleUrls: ["./recipes-list.component.css"],
})
export class RecipesListComponent implements OnInit {
  recipes: Recipe[];
  recipesChangeSub: Subscription;

  constructor(private recipesServices: RecipesServices) {}

  ngOnInit() {
    this.recipes = this.recipesServices.getRecipes();
    this.recipesChangeSub = this.recipesServices.recipesChangeSubject.subscribe(
      (recipes: Recipe[]) => {
        this.recipes = recipes;
      }
    );
  }

  ngOnDestroy(): void {
    this.recipesChangeSub.unsubscribe();
  }
}

I don't understand why my service id indeed triggering a change in my component for adding, delete and updating a recipe in my array, but not after setting this array in my setRecipes method...

I understand I could use a BehaviorSubject but I don't get why the subject doesn't fit as a solution here...

I'm very grateful for your help here :)

4

There are 4 answers

0
THaulbert On

I'm updating my situation here. You need to know how dumb I was.. XD I was just having another instance of my service running.. After deleting other instances, everything is running smooth..

Thank you again for your help :) We can close this subject

1
Behram Bazo On
setRecipesFromFetch(recipesFromFetch: Recipe[]) {
  this._recipes = recipesFromFetch; 
  this.recipesChangeSubject.next([...this._recipes]);
}

I'm not sure but fix it like this and try. I hope it works.

1
Nazeeh On

try this :

this.recipesChangeSub = this.recipesServices.recipesChangeSubject.subscribe(
  (recipes: Recipe[]) => {
    this.recipes = recipes;
  }
);
this.recipes = this.recipesServices.getRecipes();

refernce : https://rxjs.dev/guide/subject

0
THaulbert On

After the answers, I updated my code as follow :

My recipes service :

private _recipes: Recipe[] = RECIPES;
  recipesChangeSubject: Subject<Recipe[]> = new Subject<Recipe[]>();
  recipesFetchBSubject: BehaviorSubject<Recipe[]> = new BehaviorSubject<
    Recipe[]
  >([...this._recipes]);

  constructor(private errorsService: ErrorsService, private router: Router) {}

  setRecipesFromFetch(recipesFromFetch: Recipe[]) {
    this._recipes.splice(0);
    for (let recipe of recipesFromFetch) {
      this._recipes.push(recipe);
    }
    this.recipesFetchBSubject.next([...this._recipes]);
  }

My Recipes List component

ngOnInit() {
    this.recipesFetchSub = this.recipesServices.recipesFetchBSubject.subscribe(
      (recipes: Recipe[]) => {
        this.recipes = recipes;
      }
    );
    this.recipesChangeSub = this.recipesServices.recipesChangeSubject.subscribe(
      (recipes: Recipe[]) => {
        this.recipes = recipes;
      }
    );
    this.recipes = this.recipesServices.getRecipes();
  }

And still for the next method to be called on my component subscription (after subject next method called in my service), I need to navigate away and back to the component to see the changes...