Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Subscribe to observable returns undefined

So I have a service that uses a dictionary to store HTTP responses (maps an id to a specific URL).

import { HttpClient} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class urlService {
  private map: Map<string, string>;

  constructor(private http: HttpClient) {
    this.map = new Map<string, string>();
  }

  public getUrl(id: string): Observable<string> {
    if (this.map.has(id)) {
      return of(this.map.get(id));
    }

    this.http.get<any>(`...sampleURL...`)
    .subscribe((result) => {
      this.map.set(id, result.url);
      return of(this.map.get(id));
    });
  }
}

However, when I try to get this url from my app component, the logged value is undefined.

this.urlService.getUrl(this.id).subscribe(
  url => console.log(url)
);

I suppose this is because in urlService.getUrl(). I have a subscription returning an Observable. Can anyone point me in the right direction to solve this issue?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I tried using switchMap, but that didn’t seem to help me.

this.http.get<any>(`...sampleUrl...}`).pipe(
  switchMap(result => {
    this.map.set(id, result.url);
    return of(this.map.get(id));
  }))
.subscribe();

>Solution :

You are not correctly returning the Observable in the current getUrl method. It doesn’t have any return value thus return undefined.

Instead, you should return Observable with the map rxjs operator.

import { map } from 'rxjs';

public getUrl(id: string): Observable<string> {
  if (this.map.has(id)) {
    return of(this.map.get(id));
  }

  return this.http.get<any>(`...sampleURL...`)
      .pipe(
        map((result) => {
          this.map.set(id, result.url);

          return this.map.get(id); 
          // Or 
          // return result.url; 
        })
      );
}

Demo @ StackBlitz

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading