【发布时间】:2021-02-28 06:04:29
【问题描述】:
我希望在单击按钮时运行此函数 getUpcomingEvents()。我将 cmets 放在函数中以帮助解释它,但要点是它接受用户选择的美国城市和州的字符串,并返回该城市所有即将发生的事件的列表。正如您在下面看到的,有两个可观察的订阅,但是问题是当您单击触发此函数调用的按钮时,直到您单击该按钮两三下才会返回所需的数组返回。我相信这是一个时间问题,可观察到一个接一个地发生。我意识到这个函数可能太长了,我想知道我是否还需要在这里使用 switchMap 或其他东西才能让这一切正常工作。如果这里有任何不清楚的地方,请告诉我,我可以澄清。不包含 HTML,因为它只是一个调用函数的按钮,函数中传递了城市和字符串。
citySearchURL = '';
metroAreaSearchURL: any;
metroID = '';
metroAreaResults: any = [];
cityResult: any;
upcomingMetroEvents: any[];
upcomingCityEvents: any[];
stateAbbrvs = {
'AL': 'Alabama',
'AK': 'Alaska',
'AS': 'American Samoa',
'AZ': 'Arizona',
'AR': 'Arkansas',
'CA': 'California',
'CO': 'Colorado',
'CT': 'Connecticut',
'DE': 'Delaware',
'DC': 'District Of Columbia',
'FM': 'Federated States Of Micronesia',
'FL': 'Florida',
'GA': 'Georgia',
'GU': 'Guam',
'HI': 'Hawaii',
'ID': 'Idaho',
'IL': 'Illinois',
'IN': 'Indiana',
'IA': 'Iowa',
'KS': 'Kansas',
'KY': 'Kentucky',
'LA': 'Louisiana',
'ME': 'Maine',
'MH': 'Marshall Islands',
'MD': 'Maryland',
'MA': 'Massachusetts',
'MI': 'Michigan',
'MN': 'Minnesota',
'MS': 'Mississippi',
'MO': 'Missouri',
'MT': 'Montana',
'NE': 'Nebraska',
'NV': 'Nevada',
'NH': 'New Hampshire',
'NJ': 'New Jersey',
'NM': 'New Mexico',
'NY': 'New York',
'NC': 'North Carolina',
'ND': 'North Dakota',
'MP': 'Northern Mariana Islands',
'OH': 'Ohio',
'OK': 'Oklahoma',
'OR': 'Oregon',
'PW': 'Palau',
'PA': 'Pennsylvania',
'PR': 'Puerto Rico',
'RI': 'Rhode Island',
'SC': 'South Carolina',
'SD': 'South Dakota',
'TN': 'Tennessee',
'TX': 'Texas',
'UT': 'Utah',
'VT': 'Vermont',
'VI': 'Virgin Islands',
'VA': 'Virginia',
'WA': 'Washington',
'WV': 'West Virginia',
'WI': 'Wisconsin',
'WY': 'Wyoming'
};
constructor(private http: HttpClient) { }
// Function takes in a user-selected city and a state separated by a comma.
// Function returns all upcoming events that match the city name.
getUpcomingEvents(cityAndState: string) {
const cityStateSplit = cityAndState.split(', ');
const city = cityStateSplit[0];
const state = cityStateSplit[1];
// Create URL to send to songkick API that returns all areas that match the city name.
this.citySearchURL = 'https://api.songkick.com/api/3.0/search/locations.json?query=' + city + '&apikey=xxxxxxxx';
const metroAreaObservable = this.http.get(this.citySearchURL);
metroAreaObservable.subscribe(
data => {
// Songkick returns two objects - a city object and a metro area object - that matches the city used in the citySearchURL,
// one that has city info and one that has it's respective metro area info. Only the metro area object
// has an "id", which can in turn be used to search for events in that area.
// Here I assign these two objects to metroAreaResults.
this.metroAreaResults = data.resultsPage.results.location;
// Because there may be some cities returned that don't match the desired state as well, Check if user-selected city
// matches songkicks returned city and state, and pull metro id.
// The metro id will be used to create a url for another API request.
for (let i = 0; i < this.metroAreaResults.length; i++) {
if ((this.metroAreaResults[i].city.displayName === city) &&
(this.stateAbbrvs[this.metroAreaResults[i].city.state.displayName] === state)) {
this.cityResult = this.metroAreaResults[i];
this.metroID = (this.metroAreaResults[i].metroArea.id.toString());
this.metroAreaSearchURL = 'https://api.songkick.com/api/3.0/metro_areas/' +
this.metroID + '/calendar.json?apikey=xxxxxxxx';
}
}
},
error => {
throw error;
},
() => { }
);
const eventsObservable = this.http.get(this.metroAreaSearchURL);
eventsObservable.subscribe(
data => {
// Array of all upcoming events in metro area
this.upcomingMetroEvents = Array.of(data)[0].resultsPage.results.event;
},
error => {
throw error;
},
() => { }
);
// Because the end goal of this entire function is to return all of the upcoming events for the
// user-selected CITY (not metro area), this for loop checks that the upcoming event's city location
// matches the user selected city, and adds it to an array. After for loop, array gets returned.
for (let i = 0; i < this.upcomingMetroEvents.length; i++) {
if ((this.upcomingMetroEvents[i].location.city.split(', ')[0]) === city) {
this.upcomingCityEvents.push(this.upcomingMetroEvents[i]);
}
}
return this.upcomingCityEvents;
}
【问题讨论】:
标签: angular typescript api rxjs observable