使用AngularJS工厂从{Parse.com}获取数据

时间:2018-01-09 11:48:08

标签: javascript angularjs angularjs-factory

我正在使用AngularJS(v1.6.7)和Parse Server(v2.3.3)开发电子商务Web应用程序。我在Parse Server中创建了类别产品类。我正在尝试为每个类别提取一定数量的产品。例如,在主页中,每个类别将检索20个产品。其他页面中的产品数量发生变化。为此,我想创建一个工厂,在任何类别中获取给定数量的产品( amount category 的产品将作为参数传递)。所以我将能够在其他控制器中重用它。我的工厂代码是这样的:

sebetimapp.factory('ProductsFactory', ['$q', function($q){
    Parse.initialize('MY_APP_ID', 'JS_KEY');
    Parse.serverURL = 'https://parseapi.back4app.com/';
    var fac = {};
    fac.getProducts = function(cat, lmt) {
        var Category = Parse.Object.extend('Category'),
            qr = new Parse.Query(Category);
        qr.get(cat, {
            success: function(res) {
                var product_dfd = $q.defer(),
                    Product = Parse.Object.extend('Product'),
                    query = new Parse.Query(Product);
                query.include('category');
                query.equalTo('category', res);
                if(lmt) {query.limit(lmt);}
                query.find({
                    success: function(results) {
                        product_dfd.resolve(results);
                    },
                    error: function(err) {
                        product_dfd.reject(results);
                    }
                });
                return product_dfd.promise;
            },
            error: function(object, error) {
            }
        });
    };
    return fac;
}]);

这是我的控制器代码块:

sebetimapp.controller('productsCtrl', ['$scope','$log','$location','$q','ProductsFactory', function($scope, $log, $location, $q, ProductsFactory) {
    var params = $location.search(); // I passed category ID as a parameter in url.
    $scope.products = function(){
        ProductsFactory.getProducts(params.cat, 20).then(function(response){
            $log.log('Successfully retrieved products.');
        }, function(error) {
            $log.log('Unable to get products.');
        });
    };
    $scope.products();
}]);

当我执行它时,会发生错误:TypeError: Cannot read property 'then' of undefined

但如果我不使用工厂并在我的控制器中定义getProducts()功能,它就可以工作。

为什么会这样?我是AngularJS的新手。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

.then()方法仅适用于Promises。您的函数似乎没有返回任何内容(因此.then()不可用)。

这可能会有所帮助:



sebetimapp.factory('ProductsFactory', ['$q', function($q) {
  Parse.initialize('MY_APP_ID', 'JS_KEY');
  Parse.serverURL = 'https://parseapi.back4app.com/';
  var fac = {};
  fac.getProducts = function(cat, lmt) {
    var Category = Parse.Object.extend('Category'),
      qr = new Parse.Query(Category);
    return qr.get(cat)
      .then(function(res) {
        var Product = Parse.Object.extend('Product'),
          query = new Parse.Query(Product);
        query.include('category');
        query.equalTo('category', res);
        if (lmt) {
          query.limit(lmt);
        }
        return query.find();
      });
  };
  return fac;
}]);




Parse JS API中的大多数方法都会返回promise。您可以直接使用它们(而不是使用successerror回调)。自从我在Parse工作以来已经很久了(我认为它已经不再可用了)所以你可能需要自己弄清楚细节.. Handy Link:http://docs.parseplatform.org/js/guide/#promises

TLDR;您的工厂函数需要返回一个承诺,但不返回任何内容,因此.then()无法使用

编辑:这是对原始代码进行微小更改的同一事情的另一种方法(但这不是最好的方法)



sebetimapp.factory('ProductsFactory', ['$q', function($q) {
  Parse.initialize('MY_APP_ID', 'JS_KEY');
  Parse.serverURL = 'https://parseapi.back4app.com/';
  var fac = {};
  fac.getProducts = function(cat, lmt) {
    var Category = Parse.Object.extend('Category'),
      qr = new Parse.Query(Category),
      // Move the deffered object out of the inner function
      product_dfd = $q.defer();
    qr.get(cat, {
      success: function(res) {
        var Product = Parse.Object.extend('Product'),
          query = new Parse.Query(Product);
        query.include('category');
        query.equalTo('category', res);
        if (lmt) {
          query.limit(lmt);
        }
        query.find({
          success: function(results) {
            product_dfd.resolve(results);
          },
          error: function(err) {
            product_dfd.reject(results);
          }
        });
      },
      error: function(object, error) {}
    });
    // Return the deferred object
    return product_dfd.promise;
  };
  return fac;
}]);