Observable not defined in facade pattern with RxJS

(After taking Gunnar's advice, I'm updating my question) @Gunnar.B

Tool for integrating with API

@Injectable({
  providedIn: 'root'
})
export class ConsolidatedAPI {
  constructor(private http: HttpClient) { }
  getInvestments(search?: any): Observable<any> {
    return this.http.get<any>(`${environment.basePositionConsolidated}`);
  }
}

This service provides the data flow and interface to components in the presentation layer

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

    constructor(private api: ConsolidatedAPI, private state: StateService) { }

    public getInvestments$(): Observable<any> {
        return this.state.getInvestments$()
    }

    public loadInvestments() {
        return this.api.getInvestments()
        .pipe(
            tap(investPortfolio => this.state.setInvestments(investPortfolio))
        );
    }
}

This service handles the business logic for the component

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

  private investments$ = new BehaviorSubject<any>(null);

  public getInvestments$() {
    return this.investments$.asObservable()
  }

  public setInvestments(investPortfolio){
    this.investments$.next(investPortfolio)
  }
}

However, the data from the API is not displaying in my HTML.

menu.component.ts

export class MenuComponent implements OnInit {
  
  investments$: Observable<any>;

  constructor( private coreService : CoreService ) {
    this.investments$ = this.coreService.getInvestments$()
   }


  ngOnInit(): void {
    this.coreService.loadInvestments();
    console.log(this.coreService.loadInvestments())
  }

}

menu.component.html

    <div>
        test
    </div>

    <div *ngFor="let investmentPortfolio of investments$ | async;">
        {{investmentPortfolio | json}}
    </div>

https://i.sstatic.net/PgF8D.png

Answer №1

When using the listInvestments method, it is important to note that it performs an asynchronous API call. Therefore, the investments property may still be undefined when you attempt to iterate over it using forEach.

It is best practice to wait until data has been loaded from the server before looping through the investments array.

One way to achieve this is by ensuring that you are inside the subscribe's next() callback where you can be certain that you have the necessary data to perform your intended action.

The CoreService class should be updated as follows:

@Injectable({
    providedIn: 'root'
})
export class CoreService {
    public investments: any;
    constructor(private api: ConsolidadoApi, private state: StateService) {}

    public createMenu(){
      this.api.getInvestments()
            .subscribe(response => {
                this.investments = response;
                this.investments.forEach(element => {
                  console.log(element)
                });
            })
       
    }
}

Additional reminder after editing the question

It's worth noting that in the ngOnInit function, the loadInvestments() method is called, which returns an observable. Observables are lazy, meaning that nothing will happen unless you subscribe to them.

To address this issue, update the line:

this.coreService.loadInvestments();

to:

this.coreService.loadInvestments().subscribe();

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

Unable to include a header in an Angular 2 HTTP request

Having trouble with the http request headers while using the following code snippet: let authToken = new Headers() authToken.append("Authorization", "xyz"); this.http.get("http://localhost:8081/hello", {headers: authToken}) .subscribe((response) =& ...

Ways to resolve the issue of data-bs-target not functioning properly in Bootstrap version 5

While viewing the Job screen in the following image, I attempted to click on "Personal," but it remained stuck on the Job screen. ...

Dealing with precompile array warning when utilizing a basic router in Angular 2

I am currently working on developing a straightforward router-based application in Angular2 using typescript. The version of Angular2 I am using is 2.0.0-rc.4, and the router version is 3.0.0-beta.1 Here is my Routes configuration- App.routes.ts import ...

Having trouble with submitting a form through Ajax on Rails 4

Having models for advertisement and messages with forms that both utilize Ajax (remote => true) for submission. The message form submits perfectly, remains on the same page, and handles the response efficiently. However, the advertisement form fails to ...

Adjust the appearance of input fields that exclusively have the value "1"

When designing my website, I encountered a problem with the style I chose where the number "1" looks like a large "I" or a small "L." I am wondering if there is a way to use JavaScript to dynamically change the font style for input fields that only contai ...

How to Generate an Array of JSON Objects in JavaScript on a Razor Page using a Custom ViewModel in MVC?

Attempting to populate the array within my script for future charting with D3.JS, I came across some issues. Following advice from this post, I used a specific syntax that unfortunately resulted in an error stating "Uncaught ReferenceError: WebSite is not ...

navigation menu 'selective emphasis' feature

I have created a JQuery script that will highlight the 'About', 'My Projects', or 'Contact Me' text on the navigation bar when the corresponding section of the page is in view. To achieve this, I am using a scroll() event list ...

How to center items within a Toolbar using React's material-ui

I need help with implementing a toolbar on a page that contains three ToolbarGroup components: <Toolbar> <ToolbarGroup firstChild={true} float="left"> {prevButton} </ToolbarGro ...

When transferring Next Js static assets to Plesk, a 500 internal server error is encountered

I've successfully deployed a Next.js app to Plesk hosting after a lot of troubleshooting. However, I'm encountering 500 internal server errors in the console when trying to access the static assets. Here's an example: GET https://nextjs-test ...

What is the best way to locate a div element with a specific style?

What is the method to locate a div element by its style? Upon inspecting the source code in IE6, here is what I find: ...an><div id="lga" style="height:231px;margin-top:-22px"><img alt="Google"... How can this be achieved using JavaScript? ...

Utilize PHP SVG images to trigger internal JavaScript code through the <img> tag

Here is a php function that generates an SVG image. public function actionJsTest() { header('Content-Type: image/svg+xml'); $svg = ''; $svg .= '<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/ ...

My Next.js application is successfully making Axios API calls to my localhost while running on the server-side

In my Next.js and React application, I am utilizing the axios library. Initially, I was able to successfully call the API from the server using getStaticProps() and render the initial data properly. However, when attempting to fetch more data from the clie ...

Is there a way to retrieve the immediate children of all elements using CSS selectors in Selenium?

Although I attempted to utilize the ">" syntax, selenium does not seem to accept it. I am aware that Xpath can be used to obtain what I need, however our project exclusively utilizes CSS selectors. My goal is to create a list containing only the immedi ...

Guide to Embedding an Image in a List in HTML

How do I resize an image according to the size specified in CSS, and ensure that it fits within a list of items where each item consists of both an image and a name? Currently, my code only displays the image in its original size. for(var i =0; i< o ...

Discover the object in the initial array that is not included in the second array using AngularJS

Imagine having these two sets of objects: first set: [ { id: "123", title: "123", options: [] }, { id: "456", title: "456", options: [ { id: "0123", t ...

What are some ways to modify attributes in a jQuery datatable?

Upon loading the page, I initially set serverside to false. However, under certain conditions, I need to change serverside to true without altering any other attributes. For example: $(tableID).DataTable({ serverSide : false; }); Changing it to: $(t ...

React not showing multiple polylines on the screen

I'm currently working on an application aimed at practicing drawing Kanji characters. To draw the lines, I'm utilizing svg. The issue I've encountered is that when I try to draw multiple separate lines using a 2D array of points for each lin ...

Bespoke search functionality using AJAX and tags in WordPress

I have created a custom search form in my WordPress theme that looks like this: <form role="search" class="form" method="get" action="<?php echo home_url('/');?>"> <input type="search" id="keyword" class="inp-search" onclick="sh ...

Experiencing delays when loading more than 200 input fields on the screen due to

So I've been working on a project that involves having potentially unlimited input fields. However, once I add around 200 items, the performance starts to degrade significantly. You can see a demo of this issue here: (To test: Focus on the last input ...

Can I use JavaScript to generate an element similar to <ion-icon name="heart"></ion-icon>?

Currently, I am utilizing a website called to incorporate icons into my buttons. It is quite straightforward with HTML when introducing a new element containing the icon. All you need to do is define a button and insert this code within it: ion-icon name= ...