TypeScript报错:Cannot read property 'indexOf' of undefined及CoffeeScript代码求助
Hey there! Let's break down how to fix that Cannot read property 'indexOf' of undefined error when converting your working CoffeeScript autocomplete code to TypeScript, plus get the TypeScript version running smoothly.
First, What's Causing the Error?
That error almost always means you're trying to call indexOf on a variable that's undefined. In your autocomplete context, the most likely culprits are:
- The AJAX response doesn't have the structure you expect (e.g.,
data.citiesorvalue.airportsis missing/undefined) - Callback function
thisbinding issues, leading to$(this.element[0])returning undefined - Missing default values for optional fields like
request.term
Fixed TypeScript Version of Your Code
Here's a rewritten version with safeguards against undefined values and proper TypeScript conventions:
// Add type definitions if you want stricter type checking interface Airport { name: string; code: string; // Add other fields from your API response here } interface City { name: string; airports?: Airport[]; // Add other city fields here } interface AutocompleteApiResponse { cities?: City[]; } (window as any).load_autocomplete_fields = (): void => { $('.airport_field').each(function(this: JQuery<HTMLElement>) { const $field = $(this); $field.autocomplete({ delay: 10, minLength: 0, source: (request, response): void => { const sourceUrl = $field.attr('data-source'); // Guard clause: exit if source URL is missing if (!sourceUrl) { response([]); return; } // Set the request term with a default empty string const searchTerm = request.term || ''; $field.attr('data-req-term', searchTerm); $.ajax({ url: sourceUrl, dataType: 'json', data: { term: searchTerm }, success: (data: AutocompleteApiResponse): void => { const results: (City | Airport)[] = []; // Only process cities if they exist in the response if (data.cities) { $.map(data.cities, (city) => { results.push(city); // Only process airports if the city has them if (city.airports) { $.map(city.airports, (airport) => { results.push(airport); }); } }); } response(results); }, // Handle AJAX failures to avoid hanging autocomplete error: (): void => { response([]); } }); } }); }); };
Key Fixes & Improvements
- Guard Clauses: We check if
sourceUrl,data.cities, andcity.airportsexist before accessing them—this prevents trying to call methods (likemap, which under the hood might useindexOf) on undefined values. - Proper
thisBinding: Using an arrow function for thesourcecallback keeps the correct context, and we store the field element in$fieldupfront to avoid confusion withthisinside nested callbacks. - Type Safety: Added interfaces for your API response to enforce structure—TypeScript will warn you if you try to access fields that don't exist, catching issues early.
- Error Handling: Added an
errorcallback to the AJAX request to ensure the autocomplete always gets a response, even if the API call fails.
Debugging Tips If You Still See the Error
- Open your browser's DevTools > Network tab, check the AJAX request's response to confirm the JSON has
citiesandairportsfields as expected. - Add
console.log(data)inside the AJAX success callback to inspect the exact response structure. - Verify that all your
.airport_fieldelements have a validdata-sourceattribute set.
内容的提问来源于stack exchange,提问作者Balance
相关产品推荐
相关产品推荐

