Javascript 在Angular中链接HTTP调用

Javascript 在Angular中链接HTTP调用,javascript,angular,typescript,api,rxjs,Javascript,Angular,Typescript,Api,Rxjs,我正在尝试使用Google Places的API获取一个包含“photo_reference”属性的响应体。有了这个属性,我想获得GooglePlace图像并调用第二个API 我有一个可以搜索位置的输入字段。通过输入字符串并单击搜索按钮,将调用此方法: @Component({ selector: 'app-search', templateUrl: './search.component.html', styleUrls: ['./search.component.css'] })

我正在尝试使用Google Places的API获取一个包含“photo_reference”属性的响应体。有了这个属性,我想获得GooglePlace图像并调用第二个API

我有一个可以搜索位置的输入字段。通过输入字符串并单击搜索按钮,将调用此方法:

@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
      }      
    });
  }
在我的另一个组件中,我尝试获取位置并将它们映射到一个具有imgUrl属性的新对象中。 我想将它们保存在一个数组中

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(),
          };
        }))
    );
  }
}
但我的问题是
img src=“[object object]”
它应该是字符串

我的问题是这一行
this.gs.getImage(loc.photos[0].photo\u reference).toString()
我试着用一个随机硬编码的img Url替换这一行,结果它成功了。显示了图像,但我无法使用此方法以字符串形式检索URL。 当然,toString()不起作用,但我不知道还能做什么

这是谷歌定位模型:

//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;
}
...
编辑:

这是我的服务: 有了这个,我调用了我的后端,它通过API从Google获取photo_引用

@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 }
    );
  }


}


@可注入({
providedIn:'根',
})
导出类谷歌服务{
url:string='1〕http://localhost:3000/';
构造函数(私有http:HttpClient){}
getLocationInfo(位置:字符串):可观察{
控制台日志(位置);
const headers=新的HttpHeaders({
“内容类型”:“应用程序/json”,
});
返回this.http.post(
this.url+'googleplace/',
{name:location},
{headers:headers}
);
}
getPoi(位置:字符串):可观察{
控制台日志(位置);
const headers=新的HttpHeaders({
“内容类型”:“应用程序/json”,
});
返回this.http.post(
this.url+'googlepoi/',
{name:location},
{headers:headers}
);
}
getImage(photoRef:string):可观察{
控制台日志(photoRef);
const headers=新的HttpHeaders({
“内容类型”:“应用程序/json”,
});
返回this.http.post(
this.url+'googlephoto/',
{photoRef:photoRef},
{headers:headers}
);
}
}
这里是我的另一个服务,它需要从其他组件发送和检索数据

@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);
  }
 
@可注入({
providedIn:'根'
})
导出类数据服务{
私有googleLocationSource=新主题();
构造函数(){}
public getLocation():可观察{
返回此.googleLocationSource.asObservable();
}
公共设置位置(gl:GoogleLocation[]){
返回this.googleLocationSource.next(gl);
}
我的问题是这行
this.gs.getImage(loc.photos[0].photo\u reference).toString()

是的,对可观察对象调用
toString()
是行不通的!:-)

您需要订阅该observable以接收其结果。有几个“”可以为您执行此操作,因此您不必处理嵌套订阅。在这种情况下,我们可以使用

但是,它有点复杂,因为您希望对返回数组中的每个元素进行调用。我们可以将每个位置映射到一个可观察调用以获取图像,并使用它创建一个可观察对象,该可观察对象发出一个包含单个可观察对象结果的数组:

this.ds.getLocation()管道(
开关映射(位置=>forkJoin(
locations.map(loc=>this.gs.getImage(loc.photos[0].photo\u参考))
)
.烟斗(
map(imgUrls=>imgUrls.map(
(imgUrl,i)=>({…位置[i],imgUrl})
))
))
)
.订阅(
locations=>this.listOfPoi=位置
);
这里的流程是:

  • switchMap
    接收位置并订阅forkJoin创建的observable
  • forkJoin
    创建一个可观察对象,该对象将从所有单个
    getImage()
    调用发出一个结果数组(图像URL)
  • map
    接收图像url数组,并将其映射到包含图像url的位置数组
  • subscribe只接收最终的数组

大概getImage会返回一个可观察到的数据,但不清楚为什么您认为toString会神奇地使其同步。请给出一个答案。是的,我知道…我如何获得该字符串的值?我尝试了管道、forkjoin、map、switchmap等,但不起作用。好吧!我提供了更多信息,这有帮助吗?不清楚是什么您已经尝试过了,我希望
forkJoin
能够起作用(假设您希望扇出多个观察值,然后获得所有结果)。我明白了,谢谢。确实我想调用每个元素,所以它有点复杂。我尝试了你的解决方案,但它说
位置。map
的类型
未知
,并且
属性“pipe”在类型“OperatorFunction”上不存在。
此.ds.getLocation()
将从类型GoogleLocation[]返回一个可观察的值btwI添加了更多信息,我不知道他们是否有帮助..再次感谢我有一个放错位置的paren。更新!非常感谢!它似乎工作正常,没有错误!!现在只是遇到CORS问题,但这是另一个问题:)再次感谢!