28

I am having an issue with my variables being undefined. I am certain this is because the observable hasn't finished. Here is the part of my code in my .ts file that is causing the issue. (I'm placing the minimum code required to understand the issue. Also myFunction gets called from a click event in the HTML).

export class myClass {
  myVariable: any;

  myFunction() {
    this.myService.getApi().subscribe(data => {
      this.myVariable = data;
    });

    console.log(myVariable) --> undefined
  }
}

So this piece of code calls a function in my service that returns some data from an API. The issue is that when I try to access the variable myVariable right outside of the subscribe function it returns undefined. I'm sure this is because the subscribe hasn't finished before I try to access myVariable

Is there a way to wait for the subscribe to finish before I try to access myVariable?

Sachila Ranawaka
  • 39,756
  • 7
  • 56
  • 80
cup_of
  • 6,397
  • 9
  • 47
  • 94

2 Answers2

16

why not create a separate function and call it inside the subscription.

export class myClass {
  myVariable: any;

  myFunction() {
    this.myService.getApi().subscribe(data => {
      this.myVariable = data;
      this.update()
    });

    this.update()
  }

  update(){
    console.log(this.myVariable);
  }
}
Sachila Ranawaka
  • 39,756
  • 7
  • 56
  • 80
  • this seems to work for me. thanks! one quick question, why does there need to be two instances of this.update()? one in the subscribe and one outside of it – cup_of Jun 20 '18 at 15:33
  • 1
    you can remove it if you want. i add it in case if you want to call it on component initialize – Sachila Ranawaka Jun 20 '18 at 15:36
  • 2
    `myVariable` when I try this method returns undefined in `myFunction` and then null in `update()` . What is the expected result of `myVariable` and should it be possible to get a status code (201/4, post request) from it? Obviously, undefined and null throw an error when using `myVariable.status` – Rin and Len Jan 30 '19 at 09:31
  • and what if the subscriber if written in service class? – TAHA SULTAN TEMURI Oct 31 '19 at 09:52
9

As you know subscriptions are executed when server return data but the out side of subscription code executed synchronously. That is why console.log outside of it executed. The above answer can do your job but you can also use .map and return observable as shown below.

let say you are calling it from s service

export class myClass {
  myVariable: any;

  // calling and subscribing the method.
  callingFunction() {

    // the console log will be executed when there are data back from server
    this.myClass.MyFunction().subscribe(data => {
      console.log(data);
    });
  }
}


export class myClass {
  myVariable: any;

  // this will return an observable as we did not subscribe rather used .map method
  myFunction() {
    // use .pipe in case of rxjs 6 
    return this.myService.getApi().map(data => {
      this.myVariable = data;
      this.update()
    });
  }

}
Aniruddha Das
  • 20,520
  • 23
  • 96
  • 132
  • 1
    Is the 2nd block of code the service and the 1st block the component that calls the service? What is the update function doing if anything, and why do I need it? – Rin and Len Jan 30 '19 at 09:24