Angular 8 does not retain class variables once the subscribe function is finished

After calling the fetchCounties() method within the subscribe function, the value assigned to the class variable counties does not persist. When I log the temporary variable data, it shows a valid list of counties, as well as this.counties inside the subscribe block. However, upon trying to access this information outside of the subscribe block, it suddenly becomes undefined. This behavior is confusing to me as someone transitioning from Java to Angular/Typescript...

public counties: ICounty[] = [];  

public getCounties(): ICounty[] {
        this.fetchCounties().subscribe(data =>{
          console.log("data");
          console.log(data);//logs correctly
          this.counties = data;
          console.log("counties inside subscribe " );
          console.log(this.counties);//logs correctly
        });
        console.log("counties outside of subscribe " );
        console.log(this.counties);//logs incorrectly (empty) >:0
        return this.removeInvalidCounties(this.counties); //passes empty counties list...
}

Answer №1

If you want to resolve this issue, consider implementing the following solution:

public getCounties(): Observable<ICounty[]> {
    return this.fetchCounties().pipe(
       map(counties => {
         // Implement your criteria here for a valid county, let's say it must have a name
        return counties.filter(county => county.name);
      }),
    );
  }

You can then consume it as an observable like this:

this.countiesService.getCounties().subscribe(counties => {...});

In your component, you can initialize the counties array like this:

counties: ICounty[];

constructor(private countiesService: CountiesService) {}

ngOnInit() {
  this.countiesService.fetchCounties().subscribe(counties => this.counties = counties);
}

The HTML markup would look something like this:

<li *ngFor="let county of counties">{{ county }}</li>

An alternative approach is to use the Async pipe to handle subscription automatically:

counties$ = this.countiesService.fetchCounties();

In the HTML template, you can display the counties using Async pipe:

<li *ngFor="let county of counties$ | async">{{ county }}</li>

================ Regarding your query about waiting for the subscription to complete before continuing, one method is to convert it into a promise, but this may not be recommended:

public counties: ICounty[] = [];

// TypeScript might show a warning that an async function should return a promise
public async getCounties() { 
  this.counties = await this.fetchCounties().pipe(take(1)).toPromise();
  return this.removeInvalidCounties(this.counties);
}

Answer №2

The reason you may be encountering issues is due to attempting to access the array before the asynchronous call has completed (fetchCounties).

public counties: ICounty[] = [];  

public getCounties(): ICounty[] {
  // step 1
  this.fetchCounties().subscribe(data =>{
  // step 3 since it is asynchronous and timing-dependent.
  });
  // step 2
  return this.removeInvalidCounties(this.counties);
}

I'm not entirely sure of your intention, but it might be advisable to execute removeInvalidCounties within the subscription.

UPDATE: If you are looking to filter the countries you intend to use, consider the following approach.

public getCounties(): ICounty[] {
  this.fetchCounties()
  .pipe(map(countries => this.removeInvalidCounties(counties)))
  .subscribe(data =>{
    this.counties = data ;
  });
}

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

angular Issue with setTimeOut() function malfunctioning

I have a div with the class alert. <div class="alert" *ngIf=alert> <h1>Copied</h1> </div> I am trying to display this div for 3 seconds. Initially, it will be hidden and after clicking a button, I run a function that cha ...

Sticky Angular header that keeps content visible while scrolling - no disappearing into the header

I came across a discussion about sticky headers and implemented the following Angular layout: <div fxLayout="column"> <div class="sticky"> <app-header></app-header> <app-navbar></app- ...

Develop a versatile class for storing an array of key-value pairs (dictionary) using TypeScript

I am looking to implement a Dictionary class in my application. I have created a class with an Array of KeyValuePair to store my list. export class KeyValuePair<TKey, TVal>{ key:TKey; value:TVal; constructor(key:TKey, val:TVal){ this.key = key; ...

I defined a `const` within the `this.api.getApi().subscribe(({tool,beauty})` function. Now I'm trying to figure out how to execute it within an `if`

I've recently set up a const variable within this.api.getApi().subscribe(({tool,beuty}). Now, I'm trying to figure out how to run it within an if statement, just like this: if (evt.index === 0) {aa} I plan on adding more similar lines and I need ...

What is the reason for receiving a JSX warning even though JSX is not being utilized in the code?

In my Vue.js component file using the Quasar framework, I have the following code block inside the <template>: <q-btn color="green" label="save & continue editing" @click="saveCase()" /> This snippet is par ...

Guide to exporting everything within a div as a PDF using Angular 2

When attempting to convert a div with the id "div1" into a PDF using JSPdf in Angular 2, everything seems to be working fine until I try to export it to PDF. Here is my code snippet: <div class="container" id="div1"> <table> <tr> & ...

After encountering an error, the puppeteer promptly shuts down the page

During my page testing, an error is thrown by a dependency. Although the error is not critical and does not impact my application, when testing with Puppeteer and encountering this error, it abruptly closes the tested page. How can I bypass this error to c ...

Defining Zepto's Velocity.js with Typescript

I've been searching for type definitions for velocity, but the only one I could find is on tsd `tsd install velocity-animate', which unfortunately does not support velocity using Zepto. Any suggestions? ...

How to package dependencies in an Angular 7 library without directly including them in the main application

In my Angular 7 project, I utilized the @angular/cli to set it up and then added a custom library using ng generate library. The application functions smoothly in dev mode without any issues. I made sure to isolate the dependencies relevant to the library ...

When you use npm uninstall, it deletes the package from package.json, but it does not remove it from the node_modules directory

After attempting to uninstall a package using npm uninstall (package_name) -s The package was successfully removed from package.json but remained in the node_modules folder. How can I effectively remove these unused packages from the node_modules folder? ...

Angular: Unable to retrieve defined data when loading a component

There is a nagging question in my mind that I hesitate to ask because deep down, I know the answer is probably staring me in the face. After struggling with code for two days straight, I am on the brink of pulling my hair out. Although I am relatively new ...

Implementing NgRx state management to track and synchronize array updates

If you have multiple objects to add in ngrx state, how can you ensure they are all captured and kept in sync? For example, what if one user is associated with more than one task? Currently, when all tasks are returned, the store is updated twice. However, ...

Comparing ESLint and TSLint: Which One Is Right for You

After looking through numerous sources, I came up empty-handed regarding this particular question. Could anyone provide insight on the drawbacks of using Eslint compared to TsLint? What are the reasons for transitioning to ESLint? ...

Transmitting an array through a query parameter from Angular 6 to PHP

Hey there! I'm currently in the process of setting up an Angular application to make a GET request to my PHP backend. The PHP code is set up to expect three parameters - two strings and an array of strings. For example, it would look something like th ...

angular contains vulnerabilities of a moderate severity level

I am encountering an issue while trying to set up the json server for a web application I am developing using Angular. Can someone provide assistance in resolving this problem? The following dependencies are at risk due to vulnerable versions: node_m ...

Fetch the JSON data and pass it to the ITest

Objective: Retrieve data from a JSON file and store it in the "test: ITest[]" array, then display it using console.log Challenge: The code is not functioning correctly. What element am I overlooking? Background: I am new to Angular Thank you! Ser ...

The menu functionality is not responding when I try to access it by tapping on the screen using Ionic

After logging in, my single screen contains a home menu with four tabs: home, about, location, more. The menu functions properly in this setup. To navigate to the home page with all tabs and the menu after login, I use the following code: this.navCtrl.push ...

Using functional components in Redux without the need for React

I have a functioning component that does not use React, but utilizes Redux as shown below: export const isAuthenticated = () => ({user}) => { console.log("user : ", user); return true; }; const mapStateToProps = (state) => { ...

The first click does not trigger the update for the md-autocomplete

After successfully implementing md-autocomplete in my Angular4 app, I encountered a problem where the options do not show up when the list is first clicked, unlike in the demo. The options only appear once a selection is made. Here is the HTML code: &l ...

Is it possible to transfer the build files from one environment to another in Angular without the need to run npm run build again

I have experience working in over three different environments with Angular. I am wondering if there is a way to reuse built files from one environment in the others without having to rebuild each time. If this is possible, I would appreciate guidance on ...