Help needed with observables - function returns without the data


#1

I am trying to authenticate to a service using http.post. It took me some time to figure out how to bypass the cross origin problem, basically disabling the check in Safari (developing on Mac). The following code works, but I need to press the login button twice to get the login to succeed.

When the loginUser function is called the first time, the console shows “undefined” the second time, it get the expected value. What am I doing wrong?

auth-service.ts

     login() {
        var headers = new Headers();
        headers.append('Access-Control-Allow-Origin','*');
        return this.http.post(this.url, "null", {headers: headers})
          .map(response => response.json());
      }

page1.ts

  loginUser() {
    this.auth.login()
    .subscribe(
      data => { this.data = data},
      err => { this.error = true }
    );
    console.log(this.data);
 }

I have tried the following approach as well but same problems.

page1.ts

loginUser() {
  console.log("Initiating Login Operation");
  this.auth.login2()
  .then(
    data => { this.data = data},
    err => { this.error = true }
  );
  console.log(this.data);
}

auth-service.ts

  login2() {
      var headers = new Headers();
      headers.append('Access-Control-Allow-Origin','*');
      if (this.data) {
          // already loaded data
          console.log("Already have data!");
         // This is where I land the second time the function is called.
          return Promise.resolve(this.data);
      }

      // don't have the data yet
      return new Promise((resolve, reject) => {
        this.http.post(this.url, "null", {headers: headers})
        .map(res => res.json())
        .subscribe(data => {
          console.log("In Subscribe Method");
          this.data = data;
          resolve(this.data);
        }, (err) => {reject(err)});
     });
  }

#2

You must understand what is async code.

loginUser() {
    this.auth.login()
    .subscribe(
      data => { this.data = data; console.log(this.data);},
      err => { this.error = true }
    );
 }

#3

I am familiar with the concept but I picked up ionic, angular and javascriot about 3 days ago and I need some pointers to understand how to make this work.

Is there a way to be notified when the data is available then? Thx for your help.


#4

Thats what he shows in his example :slight_smile: The first argument of the subscribe method is a fat-arrow function which executes when the promise is resolved.

you could also handle it like this.

loginUser() {
    this.auth.login()
    .subscribe(
      data => { setData(data) }
      err => { this.error = true }
    );
 }
setData(data) {
 this.data = data;
console.log("Data is set to", data);
}

the setData will be called once the promise is resolved :slight_smile:


#5

Thank you. It helped.