The data stored in the variable cannot be accessed when calling it in a different method

Within my component, there are several methods including constructor(){...} and ngOnInit(){...}. I have declared a variable named values:any=[] in the class, and it is initialized with JSON data within a method called getData().

getData(){
  this.service.getData().subscribe(res=>{
    this.values = res.json();
  })
}

I then call this getData() method in ngOnInit(){...}. After this call, I observe that values is indeed populated with data. However, when I try to access values in another method for displaying purposes, it shows up as an empty array.

export class AccountComponent implements OnInit {

  values:any=[];

  constructor(private service: AccountService) {
  }

  getData(){
    this.service.getData().subscribe(res=>{
      this.values = res.json();
    })
  }

  callData(){
       console.log(this.values)  
   } 

  ngOnInit() {
    this.getData();
    this.callData();
  }

In the callData() method, I use console.log(), which displays that values is empty. But why does this happen?

Answer №1

It's true, you won't be able to retrieve data because the http call to get the data has not yet been completed.

If you want to ensure that data is retrieved in the callData method, you can utilize async/await like so:

 async getData(){
     const res =  await this.service.getData().toPromise();
      this.values = res.json();
  }

  async ngOnInit() {
    await this.getData();
    this.callData();
  }

  callData(){
       console.log(this.values)  
   } 

Essentially, you need to wait for the serverside call to finish before proceeding. Currently, you are not waiting for the serverside call to complete, which is why data is not being retrieved in your this.calllData() method.

or

If you prefer not to use async/await, you have an alternative method:

getData(){
    this.service.getData().subscribe(res=>{
      this.values = res.json();
      this.callData();
    })
  }

  callData(){
       console.log(this.values)  
   } 

 ngOnInit() {
    this.getData();
  }

Answer №2

Here's an additional solution I've used in a similar case: implementing the 'setTimeout' function.

  getData(){
    this.service.getData().subscribe(res=>{
      this.values = res.json();
    })
  }

  callData(){
       console.log(this.values)  
   } 

  ngOnInit() {
    this.getData();
    setTimeout(() => {
       this.callData();
    }, 10);
  }

By adding a small delay to the code block that relies on values returned in response, you can ensure smooth operation. I personally used a wait time of 1 millisecond and it has always been reliable for me.

Additionally, when traversing JSON objects, consider returning the JSON directly from the service method. To loop through the object without using 'foreach', you can try the following snippet:

for(let key in json){
    let value = json[key];
    //rest of the code
}

I hope this suggestion is helpful!

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

Is the child component in Angular re-rendered or re-initialized?

Recently started working with Angular(14) and encountered a problem. Whenever I update a property of the parent component, which is an array, the child component gets re-initialized (running the ngOnInit function). This issue arises when using the child co ...

Angular version 8.2 combined with Firebase can result in errors such as those found in the `./src/app/app.module.ngfactory.js` file towards the end of the process when attempting to build with

My first time posing a query on this platform, and certainly not my last. The issue at hand involves the ng-build --prod process failing to complete and throwing errors in my Angular 8.2.14 application. I've integrated Firebase into my project succes ...

Design a data structure that encompasses the combined output of multiple functions

I have a set of functions and I want to combine the return types of these functions into a union type. Example Input function types: type InputType1 = () => {type: "INCREASE"} type InputType2 = () => {type: "ADD", by: number} Ou ...

Restrict the object field type to an array by analyzing control-flow for accessing elements within brackets

Enhancements in type narrowing using control-flow analysis for bracket element access have been introduced in TypeScript 4.7. One thing I'd like to do is verify if the accessed field is an array or not. Currently, the type guard seems to be ineffecti ...

Angular 2: Harnessing the power of Observables with multiple Events or Event Handlers

In the component template, I have grouped multiple Inputs and their events like this: <tr (input)="onSearchObjectChange($event)"> <th><input [(ngModel)]="searchObject.prop1"></th> <th><input [(ngModel)]="searchObje ...

I can't seem to understand why the error "bash: ng: command not found" keeps popping up even though I

Ever since I installed Angular CLI and started working with Angular, something strange happened - the ng command suddenly became not found: ng serve -o Here's a screenshot for reference: bash: ng: command not found Oddly enough, when I use the npx c ...

Error in Typescript for a function that accepts several types of lists - property does not exist on the interface

In my project, I have defined three interfaces: a base interface and two others that extend the base one with children as properties. One of the interfaces includes 'valueType' while the other includes 'returnType'. Here is how they are ...

An error has occurred: Cannot locate a difference supporting the object '[object Object]' of type 'object'. The NgFor only enables binding to Iterables like Arrays

I've already checked for similar questions, but none of them provided a solution that worked for me. I'm facing an issue when receiving an object with the following structure: { "_embedded": { "students": [ { ...

Incorporate an external library

I am currently facing a challenge in my angular2 project where I need to import a 3rd party library. Here are the steps I have taken so far: ng new myproject npm install --save createjs-easeljs npm install @types/easeljs However, I am stuck at this poin ...

How to make Angular resolver and component share an injected service?

In my products list component, I have a table displaying various products. Since there is a considerable amount of data, I implemented a resolver to prevent the user from being directed to the page until all the data is loaded. The resolver currently utili ...

Learn how to dynamically disable a button based on the input state matching an email pattern!

I'm facing an issue with my login form that has 2 input fields and a login button. One of the input fields requires a valid email pattern. If any of the input fields are left empty, the login button becomes disabled. However, when an incorrect email p ...

Setting up a custom PrimeNG theme to match our unique style is a great way to

I am currently using the most recent version of "primeng": "^12.2.0", and I am looking to implement my own custom theme for primeng. Despite searching through numerous blogs, I have yet to find a solution. In an attempt to create my cu ...

What does an exclamation mark signify in Angular / Type Script?

Being a newcomer in the world of front end development, I am currently teaching myself Angular (11.2.10). While exploring a sample project, I noticed this particular piece of html template code written by another person and utilized in multiple places: < ...

I am struggling to understand the significance of the $ symbol in this particular context

I came across the following snippet in a book I've been reading: `images/${Date.now()}.jpg` The curly brackets used here signify 'out of string', but I'm unsure about the meaning of $... P.S. Honestly, I didn't want to ask a que ...

Achieving Bi-Directional Data Binding with Vue.js using the vue-property-decorator Library

Currently, I am working with Vue.js and TypeScript while also utilizing the vue-property-decorator. My goal is to establish two-way data binding between a parent and child component. Below is an example of what I have in mind: Parent Component <templa ...

Experiencing issues with importing .scss files after upgrading Angular and Bootstrap versions

After creating a jhipster application, I initially used Angular version 14. However, I later decided to upgrade it to version 16. Upon running "ng build," an error occurred in the following code snippet: @import '~bootswatch/dist/materia/variables&apo ...

Directive for Angular 2: Expand Further

Looking to create a custom readmore directive in Angular2 that will collapse and expand long blocks of text based on a specified max height, rather than character count. The directive will include "Read more" and "Close" links. <div read-more [maxHeigh ...

The absence of a `require` definition in Typescript combined with daisyui

Considering using typescript with react and daisyUI (a tailwindCSS component). Just a heads up, I'm currently utilizing vite In my ts.config file, I've specified node as moduleResolution Encountering an error in the tailwind config stating &apo ...

After compiling, global variables in Vue.js 2 + Typescript may lose their values

I am currently working on a Vue.js 2 project that uses Typescript. I have declared two variables in the main.ts file that I need to access globally throughout my project: // ... Vue.prototype.$http = http; // This library is imported from another file and ...

What steps should I take to enable WebStorm to recognize and offer auto-complete suggestions for component names within a personalized Angular Library?

I've run into an issue with WebStorm not recognizing a custom Angular library that I built using the generate library command. The library is correctly published on NPM with all the necessary files like umd, es2015, and fes2015, specified in the packa ...