Get string value from Observable<string> in typescript and Angular

I want to get string value from Observable and return the value from the function to the caller function.

For eg: I have array of keys and would like to fetch the value (string) of all key one by one and display it html component which has menu bar.

Here are the ts files:

key-list.component.ts

public data = [ { 'key': 1, 'value' : this.getValue(1)}, 
                { 'key': 2, 'value' : this.getValue(2)}, 
                ...
              ];

private getValue(key: number): string {
    return this.keyService.find(key).subscribe(response => {
         return response;
    });
}

keyService.ts

...
public find(key:number): Observable<any> {
  return this.http.get(`/api/keys/${key}`).map(res => res.json() || {});
}
...

I want to display all the values in the html component. But getting error in key-list.component.ts that observable into type string.

How I can solve this subscription methodolgy and make sure that getValue should always return string, and make it flawless.

One of the solution is:

private getValue(key: number): string {
        let result: string;
        this.keyService.find(key).subscribe(res => result = res);
        return result;
    }

The above solution doesn't work always. What are the alternatives solution for this kind of problem?

1 answer

  • answered 2017-08-12 16:42 Pengyy

    You are trying to return Observable from function getValue, and return response or return result won't work because request for http.get is asynchronous.

    Here are some options what you can do:

    Option1: using Async Pipe at your template to subscribe for result of http.get and remove subscribe part from function getValue.

    <div *ngFor="let item of data">
      <span>{{item.value | async}}</span>
    </div>
    
    // return Observable and subscribe by async pipe at template
    private getValue(key: number): string {
      return this.keyService.find(key);
    }
    

    Option2: Define the array data without value field and update its value field later. But be careful that the value field will be undefined unless you get response from this.keyService.find(key).

    public data = [
      { 'key': 1}, 
      { 'key': 2}, 
      ...
    ];
    
    constructor() {
      this.data.forEach(item => {
        this.keyService.find(item.key).subscribe(response => {
          item.value = response;    // update value field here.
        });
      });
    }
    
    // here getValue function is no longer necessary.
    

    Hope this will help.