1

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 :)

THaulbert
  • 25
  • 1
  • 4
  • when do you call setRecipesFromFetch or addRecipe? make sure it is called AFTER you subscribe to your subject, otherwise take a look at ReplaySubject https://rxjs.dev/api/index/class/ReplaySubject – scy Dec 31 '22 at 22:41

4 Answers4

0
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.

Behram Bazo
  • 230
  • 2
  • 6
  • Hi @Behram Bazo ! Thank you for the answer. I can' figure out why but this._recipes = recipesFromFetch; doesn't work. When doing this my component still use the old array as no value is emmited form subject. I must indeed (using the for loop) navigate to other component then go back to recipes component for the subscribe method to call next... very strange.. – THaulbert Dec 31 '22 at 18:52
0

try this :

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

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

Nazeeh
  • 45
  • 1
  • 10
  • Hello @Nazeeh ! Thank you for your help. I did change it and it still doesn't work. Thank you anyway :) – THaulbert Dec 31 '22 at 18:48
0

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...

THaulbert
  • 25
  • 1
  • 4
0

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

THaulbert
  • 25
  • 1
  • 4