Having trouble fetching information from an rxjs observable

My service offers a collection of 'Recipe' objects that can be observed

@Injectable({
  providedIn: 'root'
})
export class RecipeService {

  recipes: Recipe[];
  private _recipesSource = new Subject<Recipe[]>();
  recipesMessage$ = this._recipesSource.asObservable();

  constructor() {
    this.recipes = new Array<Recipe>();
    this.recipes.push(new Recipe('Recipe1', 1));
    this.recipes.push(new Recipe('Recipe2', 2));
    this.recipes.push(new Recipe('Recipe3', 3));
    this._recipesSource.next(this.recipes);
  }
}

In addition, there is an Angular component that generates a vertical button list for each recipe from the RecipeService

@Component({
  selector: 'app-recipe-list',
  template: `
    <div class="btn-group-vertical">
      <button
        *ngFor="let recipe of rs.recipesMessage$ | async"
        type="button" class="btn btn-secondary">
        a
      </button>
   </div>
  `
})
export class RecipeListComponent implements OnInit {

  recipes: Recipe[];
  constructor(private rs: RecipeService) { }

  ngOnInit(): void {
    this.recipes = new Array();
  } 
}

The problem I'm facing is that the buttons are not being displayed when the page loads. It seems like my subscription is returning empty results.

PS: Please excuse any shortcomings in my TypeScript skills. I am new to the world of JavaScript and always appreciate feedback.

Answer №1

The issue lies in the usage of Subject and passing values to it within the constructor.

Since Subject is a hot Observable, when values are pushed to it, they are emitted immediately. In this case, when Angular executes the constructor function for your RecipeService, the template of RecipeListComponent may not be ready yet, causing the | async to not have fired.

To handle such situations, developers often turn to using a BehaviorSubject. This type of Subject retains the most recently emitted value for late subscribers:

private _recipesSource = new BehaviorSubject<Recipe[]>([]);

Answer №2

The reason for this issue is that the Angular change detection system does not detect changes in the 'recipes' variable when it is modified within an asynchronous subscription.

To resolve this, update

*ngFor="let recipe of recipes"

to

*ngFor="let recipe of rs.recipesMessage$ | async"

You can also remove

this.loadRecipes(): void {
    this.rs.recipesMessage$
      .subscribe(
        recipes => this.recipes = recipes
      );
  }

as well as

this.loadRecipes() inside ngOnInit

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

Efficiently load Angular modules only when needed on different routes

My Angular project utilizes lazy loading for modules and below are the defined routes: { pathMatch: 'full', path: '', loadChildren: () => import('./pages/landing/home-page/home-page.module').then(m => m.Hom ...

How can we transform an object into an array using Typescript generics?

Can someone help me with this function? export const ObjectToArray = <T>(object: T): { key: unknown; value: unknown }[] => Object.entries(object).map(o => ({ key: o[0], value: o[1] })); I'm trying to remove the any part from the result ...

Upon initiating a refresh, the current user object from firebase Auth is found to be

Below is the code snippet from my profile page that works perfectly fine when I redirect from the login method of AuthService: const user = firebase.auth().currentUser; if (user != null) { this.name = user.displayName; this.uid = user.uid; } e ...

Tips for populating all the ionic form fields using speech recognition technology

In the process of developing an Ionic 4 application, I am faced with a challenge where I need to fill in multiple form fields using the Ionic speech-recognition plugin. Currently, I am only able to populate one field at a time. What I am looking for is a w ...

In Angular, the text box in a dropdown will be enabled or disabled based on the chosen selection values

I have written code for a dropdown with two values - Enabled and Disabled. Depending on the selection, I want the textbox to be enabled or disabled. Can someone help me with how to achieve this? import { Component, OnInit } from '@angular/core'; ...

Exploring image cycling functionality in Angular by leveraging button clicks and services

I've been experimenting with cycling through images using button clicks in my code, but I haven't had much success so far. I tried a routing approach that didn't work out, resulting in me deleting the code. If anyone has any suggestions or c ...

Pathways and Components

I have set up the following routing configuration in my application: app.module.ts @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpModule, AppRouting, // Feature Modules CoreModule, AuthModule, ...

During operation, zxing/ngx-scanner functions properly on Safari but encounters issues on Chrome

Encountering an Issue: Despite implementing HTTPS, Chrome is encountering difficulties when attempting to open the zxing/ngx-scanner, resulting in the following error message: @zxing/ngx-scanner Error when asking for permission. DOMException: Permission de ...

Implementing React Router with dynamic parameters in the root element

I'm in the process of transforming an ASP.NET MVC application to utilize React with Redux in TypeScript. I've opted for React Router for handling the routing, with a necessary parameter in the root URL to specify the customer's organization. ...

Is there a way to obtain a unique response in TestCafe RequestMock?

With Testcafe, I have the capability to simulate the response of a request successfully. I am interested in setting up a caching system for all GET/Ajax requests. The current setup functions properly when the URL is already cached, but it fails to prov ...

The angular mat-checkbox [checked] property is being triggered multiple times when dynamically assigning a value

<ul> <li *ngFor=let choice of checkboxlist.options> <mat-checkbox [checked]=isChecked(choice) > <mat-checkbox> <li> <ul> Within my TypeScript file, I have a function called isChecked which determines whether a checkbox ...

Setting various colors for different plots within a single chart: A step-by-step guide

I'm currently tackling a project that requires me to showcase two different plots on the same chart, one being a "SPLINE" and the other a "COLUMN". My aim is to assign distinct background colors to each of these plots. Please note that I am referring ...

Get the shared elements from several arrays with JavaScript

Find the shared value of 12 from the given array For example: If the input is as follows: [ [12, 6],[12, 11, 9, 8, 1],[12, 11, 9, 8, 6, 1],[12, 11, 9, 8, 6, 1],[12, 11, 9, 8, 6, 1] ] The expected Output should be : [12] ...

BehaviorSubject Observable continuously notifies unsubscribed Subscription

Utilizing a service called "settings", initial persisted values are read and provided through an observable named "settings$" to components that subscribe to it. Many components rely on this observable to retrieve the initial values and exchange updated va ...

Tips for customizing Material UI CSS default properties in React

I'm currently working on a React project and utilizing the 'Table' component from Material UI. The default CSS properties of this table, along with its components like TableHead, TableCell, and TableRow, are proving difficult to override whi ...

Using Webpack to manage environment variables in Typescript

Having some issues declaring global variables in Typescript with Webpack's DefinePlugin. Seeking assistance to identify what might be going wrong. Implemented an environment variable in my .bash_profile: export API_KEY_GOOGLE_MAPS=xxxxxxxxxxxxxxxx ...

Is there a way to toggle glyphicons in Angular 2 while also triggering their functions? Maybe using *ngIf?

I am working on a feature to add items to favorites in my Angular 2 app. The code snippet provided below is able to display either a filled star or an empty star based on the current status of the object. It also triggers the appropriate function to favori ...

Utilizing Angular 4 Dropdowns: A Practical Demonstration

I was looking for a way to incorporate a drop-down text into one of my form elements, and I stumbled upon this resource: ng4-material-dropdown However, the instructions on how to use it are not very clear from the provided example: The example code snipp ...

Programmatically toggle the visibility of an ion fab button

Looking for assistance in finding a method to toggle the visibility of a particular button within the collection of buttons in an ion-fab https://i.sstatic.net/vkFrP.png ...

Leveraging the power of the map function to manipulate data retrieved

I am working on a nextjs app that uses typescript and a Strapi backend with graphql. My goal is to fetch the graphql data from strapi and display it in the react app, specifically a list of font names. In my react code, I have a query that works in the p ...