I'm trying to get Google Places with their API and get a response body that contains a "photo_reference" property. With this property, I want to get the Google Place Image and call a second API.
I have an input field that can search for places. By entering a string and clicking on the search button, this method will get called:
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
private lng: number;
private lat: number;
private place_id: string;
private listOfPoi: GoogleLocation[];
constructor(
private gs: GoogleService,
private ds: DataService,
private router: Router
) { }
ngOnInit(): void {
this.ds.getLocation().subscribe(loc => this.listOfPoi = loc);
}
searchPoi(location: string): void {
this.router.navigate(['/poi']);
this.gs.getPoi(location).pipe(
map((response) => response)
).subscribe((data: GoogleResponse) => {
if(data.status === "OK") {
this.ds.setLocation(data.results); //data.results is an array of locations
}
});
}
In my other component, I try to get the locations and map them into a new object with the property imgUrl. I want to save them in an array.
export class SightseeingViewComponent implements OnInit {
listOfPoi: LocationWithImage[];
constructor(private ds: DataService, private gs: GoogleService) {}
ngOnInit(): void {
this.ds.getLocation().subscribe(
(loc) =>
(this.listOfPoi = loc.map((loc) => {
return {
...loc,
imgUrl:
this.gs.getImage(loc.photos[0].photo_reference).toString(),
};
}))
);
}
}
But my problem is the img src="[object Object]" it should be the string!
My problem is this line this.gs.getImage(loc.photos[0].photo_reference).toString()
I tried to replace this line with a random hardcoded img Url and it works. The image are shown but I cannot retrieve the URL as string with this method.
Of course toString() is not working but I have no clue what else I can do?
This is the google location model:
//The model of a google location object from the API response (getLocationInfo)
export class GoogleResponse {
constructor(
public results: GoogleLocation[],
public status: string
) {}
}
export class GoogleLocation {
constructor(
public formatted_address: string,
public geometry: Locations,
public icon: string,
public name: string,
public photos: PhotoInfo[],
public place_id: string,
public reference: string,
public type: string[]
) {}
}
export interface LocationWithImage extends GoogleLocation {
imgUrl?: string;
}
...
EDIT:
This is my service: With this, I make a call to my backend which is fetching the photo_reference from Google via its API
@Injectable({
providedIn: 'root',
})
export class GoogleService {
url: string = 'http://localhost:3000/';
constructor(private http: HttpClient) {}
getLocationInfo(location: string): Observable<GoogleResponse> {
console.log(location);
const headers = new HttpHeaders({
'Content-Type': 'application/json',
});
return this.http.post<GoogleResponse>(
this.url + 'googleplace/',
{ name: location },
{ headers: headers }
);
}
getPoi(location: string): Observable<GoogleResponse> {
console.log(location);
const headers = new HttpHeaders({
'Content-Type': 'application/json',
});
return this.http.post<GoogleResponse>(
this.url + 'googlepoi/',
{ name: location },
{ headers: headers }
);
}
getImage(photoRef: string): Observable<string> {
console.log(photoRef);
const headers = new HttpHeaders({
'Content-Type': 'application/json',
});
return this.http.post<string>(
this.url + 'googlephoto/',
{ photoRef: photoRef },
{ headers: headers }
);
}
}
Here is my other service which is needed to send and retrieve data from other components
@Injectable({
providedIn: 'root'
})
export class DataService {
private googleLocationSource = new Subject<GoogleLocation[]>();
constructor() { }
public getLocation(): Observable<GoogleLocation[]> {
return this.googleLocationSource.asObservable();
}
public setLocation(gl: GoogleLocation[]) {
return this.googleLocationSource.next(gl);
}
forkJointo work (given you want to fan out to multiple observables then get all of the results).