如果Observable没有返回正确的响应,我该如何继续运行for循环。

时间:2022-10-14 17:06:24

Im using the Google maps API to let a user search for a city and then I query my Firebase database based on the addressType. The google response returns different addressTypes (locality, add_level_1, add_level_2, ...), and I want to be able to execute different queries if I don't get a result.

我使用Google maps API让用户搜索某个城市,然后根据addressType查询我的Firebase数据库。谷歌响应返回不同的addressTypes(locality,add_level_1,add_level_2,...),如果我没有得到结果,我希望能够执行不同的查询。

How my project should work: I get the object of the Google API, then based on that information I search for POI, first based on 'locality', if that doesn't return a result (no objects found in firebase) I execute the same query but based on 'adm_level_2', and so on.

我的项目应该如何工作:我得到Google API的对象,然后基于我搜索POI的信息,首先基于'locality',如果没有返回结果(在firebase中找不到对象)我执行相同的查询,但基于'adm_level_2',依此类推。

What I've got so far: I'm able to get the Google API response and then execute the query to find POI based on 'locality', and show that response in my app. But I can't figure out how to execute a second (and third) query if the first query doesn't return a result.

到目前为止我得到了什么:我能够获得Google API响应,然后执行查询以根据“位置”查找POI,并在我的应用中显示该响应。但是,如果第一个查询没有返回结果,我无法弄清楚如何执行第二个(和第三个)查询。

My code so far:

我的代码到目前为止:

 var componentForm = {
        street_number: 'short_name',
        route: 'long_name',
        locality: 'long_name',
        administrative_area_level_1: 'short_name',
        administrative_area_level_2: 'long_name',
        country: 'long_name',
        postal_code: 'short_name'
      };

  for (var i = 0; i < place.address_components.length; i++) {
    this.addressType = place.address_components[i].types[0];
    if (componentForm[this.addressType]) {
      if (this.addressType == "locality") {
        this.locality = place.address_components[i][componentForm[this.addressType]];
         let rsltBusiness = [];
         self._dataService.getCompaniesForLocationObs(this.addressType,this.locality)
          .map(i=>{return i})
          .subscribe(i => self.staticData =i
          );
      }
      if (this.addressType == "administrative_area_level_2") {
        console.log("adm_level_2 ");
        this.adm_level2 = place.address_components[i][componentForm[this.addressType]];
      } if (this.addressType == "administrative_area_level_1") {
        this.adm_level1 = place.address_components[i][componentForm[this.addressType]];
      }
    }
  }

So the first part that works is in the ' if (this.addressType == "locality")' but if that doesn't return a result I should be able to execute the same query but then from 'if (this.addressType == "administrative_area_level_2") {'

所以第一部分工作在'if(this.addressType ==“locality”)'但是如果没有返回结果我应该能够执行相同的查询但是然后从'if(this.addressType = =“administrative_area_level_2”){'

Is that possible? And if yes, how should I handle that? Or am I trying to do something that is against the proper use of Observables and Angular2 / Firebase?

那可能吗?如果是的话,我应该如何处理?或者我试图做一些反对正确使用Observables和Angular2 / Firebase的东西?

I don't have a lot of experience with Angular2 so any help would be greatly appreciated.

我对Angular2没有很多经验,所以任何帮助都会非常感激。

1 个解决方案

#1


0  

Not sure this is gonna work out of the box, since I can't test the code, but I'll try to explain the principal, you implement it:

不确定这是否可以开箱即用,因为我无法测试代码,但我会尝试解释主体,你实现它:

// create a list of types you want to check against from API response

  let addressTypes = [];
  let addressLocality = {};
  for (var i = 0; i < place.address_components.length; i++) {
    let type = place.address_components[i].types[0]
    addressTypes.push( type );
    addressLocality[ type ] = place.address_components[i][componentForm[type]]
  }

// Search database for each 'addressType' you found.
   Observable.from(addressTypes)
     .mergeMap(type => self._dataService
       .getCompaniesForLocationObs(type, addressLocality[type]))

// Assuming 'getCompaniesForLocationObs()' returns false if it doesn't find anything
      .filter(Boolean)

// If something is found stop 
       .take(1)

// Execute!
       .subscribe(i => self.staticData = i)

Remember, observable evaluates whole chain of operators you set up for each source item before evaluating next one. So you just need to create a list of things you want to query from API response (my for-loop will probably not work) and let observable do it's thing (;

请记住,observable在评估下一个源项之前评估为每个源项设置的整个运算符链。所以你只需要创建一个你想要从API响应中查询的东西的列表(我的for循环可能不起作用),让observable做它的事情(;

And don't forget imports:

不要忘记进口:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/take'; 
import 'rxjs/add/operator/filter'; 

#1


0  

Not sure this is gonna work out of the box, since I can't test the code, but I'll try to explain the principal, you implement it:

不确定这是否可以开箱即用,因为我无法测试代码,但我会尝试解释主体,你实现它:

// create a list of types you want to check against from API response

  let addressTypes = [];
  let addressLocality = {};
  for (var i = 0; i < place.address_components.length; i++) {
    let type = place.address_components[i].types[0]
    addressTypes.push( type );
    addressLocality[ type ] = place.address_components[i][componentForm[type]]
  }

// Search database for each 'addressType' you found.
   Observable.from(addressTypes)
     .mergeMap(type => self._dataService
       .getCompaniesForLocationObs(type, addressLocality[type]))

// Assuming 'getCompaniesForLocationObs()' returns false if it doesn't find anything
      .filter(Boolean)

// If something is found stop 
       .take(1)

// Execute!
       .subscribe(i => self.staticData = i)

Remember, observable evaluates whole chain of operators you set up for each source item before evaluating next one. So you just need to create a list of things you want to query from API response (my for-loop will probably not work) and let observable do it's thing (;

请记住,observable在评估下一个源项之前评估为每个源项设置的整个运算符链。所以你只需要创建一个你想要从API响应中查询的东西的列表(我的for循环可能不起作用),让observable做它的事情(;

And don't forget imports:

不要忘记进口:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/take'; 
import 'rxjs/add/operator/filter';