You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS项目ES6改造后Factory调用then()报错求助

Fixing "then() is not a function" in AngularJS Factory with ES6 Arrow Functions

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:06:15