2

I'm trying to get data from an API with a service. And then log it from inside a module which is later going to show it in a list. The variable shows up in the console.log in the service but not when I try to log it in de module

This same set up i've made before with ionic, I figured angular would work the same but that isn't the case here. I've already expanded the .subscribe function with error handling but no errors show up. I just don't know where to look.

api.service.ts

getPlacesData(): any {
    let result = this.http.get(`${this.apiUrl}/places`, this.httpOptions).pipe(
      map(response => {
        console.log(response['data']);
        response['data'];
      })
    );
    return result;
  }
}

test-dashboard.component.ts

constructor(private breakpointObserver: BreakpointObserver, private apiService: ApiService) {}

  getPlacesData() {
    this.apiService.getPlacesData().subscribe(
      (placesData: Observable<any>) => {
        console.log(placesData);
        this.placesData = placesData;
        console.log(this.placesData);
      },
      (error: string) => {
        console.log('Received an errror: ' + error);
      }
    );
  }

  ngOnInit() {
    this.getPlacesData();
  }
}

I expect the second and third console.log to have the same output as the first one, but the output from those is "undefined" instead of:

(15) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

2
  • 1
    You need to make sure to actually return the response inside the map(), currently you aren’t returning anything implicitly or explicitly. Commented Sep 10, 2019 at 13:54
  • 1
    You currently don't return anything in your map function
    – Florian
    Commented Sep 10, 2019 at 13:55

3 Answers 3

2

The issue is that you are trying to return a value synchronously. Angular https requests are asynch. Please treat them as such. Your function should return the Observable. Use async pipe in your html template to access the data after.

getPlacesData(): Observable<Places[]> {
    return this.http.get<Places[]>(`${this.apiUrl}/places`, this.httpOptions).pipe(
      map(response => response['data']),
    );
  }
}
3
  • Thanks for your response, stupid mistake on my part for putting the return in the wrong place. I've edited my code to look like the one you provided but now it says that it can't find the name 'Places'. Do I need to define it anywhere first? I've read online it's something to with the import but I don't know what to change import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; Commented Sep 11, 2019 at 7:44
  • I have fixed this issue by changing it to this: ` getPlacesData(): Observable<any[]>` I don't know what the fallout of this is later in my project, but for now my issue is solved. Thanks everyone for responding! Commented Sep 11, 2019 at 8:06
  • Places would be an interface/class you could create. It is recommended to define it, that's why I added it. Any's should be avoided. Commented Sep 11, 2019 at 11:41
1

Try something like this

getPlacesData(): any {
return this.apiService.get(this.terminateSurveyUrl, terminateSurveyReqObj)
  .pipe(
    map((response:any) => {
      console.log('response',response);
      return response.data;
    }),
  )
}

Hope it helps!

0

You have to return data in your map function

  map(response => {
    console.log(response['data']);
    return response['data'];
  })

or

  map(response => response['data'])

Also in your subscription type of value is not Observable any more in your case it will be Array

(placesData: Array<any>)

Not the answer you're looking for? Browse other questions tagged or ask your own question.