AngularJS项目ES6改造后Factory调用then()报错求助
Hey there! Let's break down why you're seeing that frustrating then() is not a function error and how to fix it.
The Root Cause
9 times out of 10, this happens because your Factory isn't returning a Promise when you call its API methods. AngularJS's $http service naturally returns a Promise, but if you forget to pass that Promise up to the controller (either by omitting a return statement or returning something else entirely), your controller will try to call then() on a non-Promise value—like undefined—which triggers the error.
Let's Look at Common Mistakes & Fixes
1. Forgetting to return the $http Promise
This is the most frequent slip-up. Here's what a wrong implementation might look like:
// ❌ Broken Factory: No return on $http call app.factory('ApiService', function($http) { return { fetchUserData: () => { // Oops! We're calling $http but not returning its Promise $http.get('/api/user'); } }; });
To fix it, just add the return keyword to pass the Promise along:
// ✅ Fixed Factory: Returns the $http Promise app.factory('ApiService', function($http) { return { fetchUserData: () => { // Now the controller gets a Promise with a then() method return $http.get('/api/user'); } }; });
2. Processing data in the Factory but not returning a new Promise
If you're transforming the API response in your Factory (like filtering data or parsing values), make sure you either return the chained Promise or use $q to create a new one.
Example with chained Promises (cleaner approach):
app.factory('ApiService', function($http) { return { fetchProcessedData: () => { // Chain the then() and return the new Promise return $http.get('/api/data') .then(response => { // Transform the data before sending to controller return response.data.map(item => ({ id: item.id, fullName: `${item.firstName} ${item.lastName}` })); }); } }; });
If you're using $q for custom async logic, don't forget to return the deferred promise:
app.factory('ApiService', function($http, $q) { return { fetchCustomData: () => { const deferred = $q.defer(); $http.get('/api/data') .then(response => { // Custom processing logic const filteredData = response.data.filter(item => item.active); deferred.resolve(filteredData); }) .catch(error => { deferred.reject(error); }); // Critical: Return the Promise here return deferred.promise; } }; });
How to Call It in Your Controller
Once your Factory is returning a Promise, your arrow function usage in the controller will work just fine:
app.controller('UserController', function(ApiService) { ApiService.fetchUserData() .then(response => { // Handle the successful response this.user = response.data; }) .catch(error => { // Handle errors gracefully console.error('Failed to fetch user data:', error); }); });
Quick Debug Tip
If you're still stuck, add a console.log() right where you call the Factory method to check what you're getting:
const result = ApiService.fetchUserData(); console.log(result); // Should log a Promise object, not undefined or a plain object
That should get your then() calls working smoothly with ES6 arrow functions in AngularJS!
内容的提问来源于stack exchange,提问作者Ellebkey

