Sandra Willford
Sandra Willford

Reputation: 3789

typescript/angular pass value out of this?

So in normal javascript if I wanted to assign a value to a variable and then use that value outside of a function it would be done by declaring the variable first and then define it's value in the function. I'm brand new to typescript and angular so I am missing how to do this.

In the code below I am trying to get the value from a method in a service and then pass that value into my return. (I hope that makes sense). However I keep getting undefined on console.log(url) with no other errors.

emailsAPI() {
    let url: any  
    this.apiUrlsService.urlsAPI().subscribe(
        data => {
            this.results = data
            url = this.results.emails
        }
    );
    console.log(url)
    return this.http.get('assets/api/email_list.json')
}

api-urls service:

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';

@Injectable()
export class ApiUrlsService {

    constructor(
        private http: HttpClient
    ) { }

    urlsAPI () {
        return this.http.get('assets/api/api_urls.json')
    }

}

Upvotes: 1

Views: 1249

Answers (3)

Ankit Kapoor
Ankit Kapoor

Reputation: 1754

As per reactive programming, this is the expected behaviour you are getting. As subscribe method is async due to which you are getting result later on when data is received. But your console log is called in sync thread so it called as soon as you are defining subscribe method. If you want the console to get printed. Put it inside your subscribe data block.

UPDATE:

As per your requirement, you should return Subject instead of Observable as Subject being data consumer as well as data producer. So it will consume data from httpget request from email and act as a producer in the method from where you called emailsAPI method.

emailsAPI(): Subject<any> {
    let emailSubject:Subject = new Subject();  
    this.apiUrlsService.urlsAPI()
        .flatMap(data => {
            this.results = data
            return this.results.emails;
        }).
        subscribe(url=> {
        this.http.get(your_email_url_from_url_received).subscribe(emailSubject);   
   });
    return emailSubject;
}

The subject can be subscribed same as you will be doing with Observable in your calee method.

Upvotes: 0

SALEH
SALEH

Reputation: 1562

emailsAPI(): Observable<any> {
    let url: any  
    return this.apiUrlsService.urlsAPI()
        .flatMap(data => {
            this.results = data
            url = this.results.emails
            // you can now access url variable
            return this.http.get('assets/api/email_list.json')
        });

}

Upvotes: 1

Mateusz Witkowski
Mateusz Witkowski

Reputation: 1746

That's because you're calling async method subscribe and then trying to log the coming value before subscription is resolved. Put last two statements (console.log and return) inside the curly braces just after assigning this.results.emails to the url variable

Upvotes: 1

Related Questions