1

I'm struggling to understand this..

In my requests.service I have this function that calls my backend:

loginUser(username, pw): Observable <any>{
    const body = {
      username: username,
      password: pw
    }
    let headers = new HttpHeaders();
    headers = headers.append("Authorization", "Basic " + btoa('test:test'));
    headers = headers.append("Content-Type", "application/json");

   return this.http.post('https://website.com/1/user/login', body, {headers: headers})
   .subscribe((data)=>{ //use methods in our service
     console.log(data)
     this.userData = data;
   }, (err)=> console.log(err));
  }

This works, the data is returned.

Now, in login.page.ts I want to call loginUser but I also want a callback on it so I know when it has successfully been run, so I do:

this.req.loginUser(info.email, info.password).then((data) => {
  console.log(data)
})

but I get the error:

this.req.loginUser(...).then is not a function

If I just console.log it with no callback it works fine, but I need to know when the call has been successful.

Any ideas?

5
  • 2
    You return a subscription not a promise, then() will never work in this example. Just do the call without the then(): this.req.loginUser(info.email, info.password); you will not need it. Commented Jun 14, 2019 at 19:17
  • Return the observable from the service... please look at the tutorial, it will help you: angular.io/tutorial/toh-pt6 Commented Jun 14, 2019 at 19:19
  • @JohnnyDevNull but how do I know when the call has executed? I need to run code after.. Commented Jun 14, 2019 at 19:19
  • just return the observable without the subscription in the service. you can .pipe(tap((data) => { ... })) if you need logic in the service and make the subscription in your component. Commented Jun 14, 2019 at 19:22
  • loginUser return a subscription object not observable please consider look to my answer πŸ‘‡ where I explain observable and promise implementation πŸ€”πŸ€” @JaneDoe Commented Jun 15, 2019 at 0:01

3 Answers 3

2

It's an observable coming back not a promise. So .then is not applicable.

this.req.loginUser(info.email, info.password).pipe().subscribe((data) => {
  console.log(data) // whenever data returns do something with it
})

We use pipe() to be able to do more things with subscriptions such as:

.pipe(
   take(1) // will allow the subscription to return 1 time then unsubscribe 
   takeUntil() // subscribe until a condition is met
   map() // map your observable
   etc.
) 
Sign up to request clarification or add additional context in comments.

1 Comment

correct but look he already subscribe inside the method check my answer πŸ˜‰
2

Since loginUser returns an Observable, you need to subscribe to it.

this.req.loginUser(info.email, info.password).subscribe((data) => {
  console.log(data)
})

1 Comment

loginUser dosn't return an observable because he subscribe inside the method is return subscription object πŸ˜‰ you answer correct in case he return the post method without the subscribe
2

you need to update the loginUser like this in case you want to use the observable and you don't need to subscribe inside the loginUser

loginUser(username, pw): Observable <any>{
    const body = {
      username: username,
      password: pw
    }
    let headers = new HttpHeaders();
    headers = headers.append("Authorization", "Basic " + btoa('test:test'));
    headers = headers.append("Content-Type", "application/json");
    const url = 'https://website.com/1/user/login';
   return this.http.post(url, body, {headers: headers}); // πŸ‘ˆ

  }

invoke the method like this πŸ‘‡

this.req.loginUser(info.email, info.password).subscribe((data)=>{ 
         console.log(data);
         this.userData = data;
}, (err)=>{
         console.log(err)
});

in case you want to use the then method and you want to invoke the method imidaily use toPromise method to convert the observable to promise

loginUser(username, pw): Promise <any>{
    const body = {
      username: username,
      password: pw
    }
    let headers = new HttpHeaders();
    headers = headers.append("Authorization", "Basic " + btoa('test:test'));
    headers = headers.append("Content-Type", "application/json");
    const url = 'https://website.com/1/user/login';
   return this.http.post(url, body, {headers: headers}).toPromise(); // πŸ‘ˆ

  }

now you can use the then method

this.req.loginUser(info.email, info.password).then((data)=>{ 
         console.log(data);
         this.userData = data;
 }).
 catch( err => console.log(err));

πŸ’£πŸ’₯

The key difference between two ways if it observable this πŸ‘‰ this.req.login User(info.email, info.password) will not run until you subscribe but in case of promise this πŸ‘‰ this.req.login User(info.email, info.password) will run the method even without using then the request will send to the server πŸ”₯πŸ”₯

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.