【问题标题】:angular.js - TypeError: Cannot read property 'then' of undefinedangular.js - TypeError:无法读取未定义的属性“then”
【发布时间】:2016-09-20 08:28:24
【问题描述】:

我正在尝试使用我的服务插入每个捕获的详细信息页面。

虽然当我尝试在我的服务中加载带有 id 的页面时(例如:/capture/5740c1eae324ae1f19b7fc30),但我得到了未定义,使用以下代码:

app.factory('captureApi', ['$http', function($http){

var urlBase = 'URL';
// ==> Gives back an array as such:
//[
//{
//  "_id": "5740c1e3e324ae1f19b7fc2f",
//  "created_at": "2016-05-21T20:15:38.554Z",
//  "userId": "118000609287736585411",
//  "place": "place",
// "birdname": "birdname",
//  "__v": 0
//},
//{
//  "_id": "5740c1eae324ae1f19b7fc30",
//  "created_at": "2016-05-21T20:15:38.554Z",
//  "userId": "118000609287736585411",
//  "place": "place",
//  "birdname": "birdname",
//  "__v": 0
//},
//{ 
//  ...
//}
//]

return {
    getAllCaptures : function () {
        return $http.get(urlBase);
    },

    insertCapture : function(data) {
        return $http.post(urlBase, data);
    },

    findCapture : function(id) {
        //both give undefined
        console.log(_.find(urlBase, function(capture){return capture._id == id}));
        console.log(_.find(urlBase, function(capture){return capture.id == id}));
        return _.find(urlBase, function(capture){return capture.id == id});
    }
    }
}]);

在服务器端,我使用的是 mongoose/mongodb:

-路线:

var Capture = require('../models/capture');
module.exports = function(router) {
    router.post('/captures', function(req, res){
        var capture = new Capture();
        capture.birdname = req.body.birdname;
        capture.place =  req.body.place;
        capture.userId = req.body.userId;
        capture.author = req.body.author;
        capture.picture = req.body.picture;
        capture.created_at = new Date();

        capture.save(function(err, data){
            if(err)
                throw err;
            console.log(req.body);
            res.json(data);
        });
    });

    router.get('/captures', function(req, res){
        Capture.find({}, function(err, data){
            res.json(data);
        });
    });

     router.delete('/captures', function(req, res){
          Capture.remove({}, function(err){
              res.json({result: err ? 'error' : 'ok'});
          });
      });

    router.get('/captures/:id', function(req, res){
         Capture.findOne({_id: req.params.id}, function(err, data){
             res.json(data);
         });
     });

     router.delete('/captures/:id', function(req, res){
         Capture.remove({_id: req.params.id}, function(err){
             res.json({result: err ? 'error' : 'ok'});
         });
     });

    // router.post('/captures/:id', function(req, res){
    //     Capture.findOne({_id: req.params.id}, function(err, data){
    //         var capture = data;
    //         capture.birdname = req.body.birdname;
    //         capture.place.city = req.body.place.city;
    //         capture.place.country = req.body.place.country;

    //         capture.save(function(err, data){
    //             if(err)
    //                 throw err;
    //             res.json(data);
    //         });
    //     })
    // })
}

-型号:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var captureSchema = mongoose.Schema({
    birdname: {type: String, required: true},
    place: {type: String, required: true},
    userId: {type: String, required: true},
    author: {type: String, required: true},
    picture: Schema.Types.Mixed,
    created_at: Date
});

module.exports = mongoose.model('Capture', captureSchema)

这是我的 server.js(额外信息):

// Init Express Web Framework
var express = require('express');
var app = express();
var path = require('path');

// Set view engine to EJS & set views directory
app.set('view engine', 'ejs');
app.set('views', path.resolve(__dirname, 'client', 'views'));

app.use(express.static(path.resolve(__dirname, 'client')));

// Database Connection
var mongoose = require('mongoose');
var configDB = require('./server/config/database.js');
mongoose.connect(configDB.url);

var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));               
app.use(bodyParser.text());                                    
app.use(bodyParser.json({ type: 'application/json'}));  

// Main route
app.get('/', function(req, res){
    res.render('index.ejs');
});

// // catch 404 and forwarding to error handler
// app.use(function(req, res, next) {
//     var err = new Error('Not Found');
//     err.status = 404;
//     next(err);
// });

// API 
var api = express.Router();
require('./server/routes/capture')(api);
app.use('/api', api);

// Set routes to other pages
app.get('/*', function(req, res){
    res.render('index.ejs');
});

// Port Settings
app.listen(process.env.PORT || 3000, process.env.IP);
console.log('Listening on port ' + process.env.PORT);

在客户端我有以下触发页面:

 $stateProvider

    .state('home', {
      url: '/',
      templateUrl: 'partials/home.html',
      controller: 'homeCtrl',
        data: {
            requiresLogin: false
        },
        resolve: {
          $title: function() { return 'Home'; }
        }
    })

    .state('dash', {
      url: '/dashboard',
      templateUrl: 'partials/dashboard.html',
      controller: 'dashCtrl',
        data: {
            requiresLogin: true
        },
        resolve: {
          $title: function() { return 'Dashboard'; }
        }
    })

    .state('capture', {
      url: '/capture',
      templateUrl: 'partials/capture.html',
      controller: 'captureCtrl',
        data: {
            requiresLogin: true
        },
        resolve: {
          $title: function() { return 'Capture'; }
        }
    })

    .state('viewCapture', {
      url: '/capture/:id',
      templateUrl: 'partials/viewCapture.html',
      controller: 'viewCaptureCtrl',
      data: {
            requiresLogin: true
        },
      resolve: {
        $title: function() { return 'Capture Detail'; }        
      }
    })

viewCaptureCtrl.js:

app.controller('viewCaptureCtrl', ['$scope', 'captureApi', '$stateParams', '$http', function($scope, captureApi, $stateParams, $http) {

     var id = $stateParams.id;

      $scope.viewCapture = function() {
        captureApi.findCapture(id)
            .then(function(data) {
              $scope.capture = data;
            });
      };

      $scope.viewCapture();

}]);

有人知道为什么我的 find 函数给出了未定义的值吗? 非常感谢您的帮助!谢谢

【问题讨论】:

  • 你确定findCapture(id) 正在返回一个承诺吗?
  • 未定义。我猜我的服务有问题,但不知道是什么问题。

标签: angularjs node.js mongodb service mongoose


【解决方案1】:

您需要引用underscoreJS 并将其注入您的服务。文档:http://app-genesis.com/underscorejswithangularjs/

var app = angular.module("app", []);
app.factory('_', function() { return window._; });

//inject into capture api factory
app.factory('captureApi', ['$http', '_', function($http, _){
    //do stuff with _
}]);

编辑:但我不熟悉_.find();如果它返回一个承诺与否。如果没有,您需要使用$q 创建一个promise 并返回它以便使用then()

//inject into capture api factory
app.factory('captureApi', ['$http', '_', '$q',
    function($http, _, $q) {
        return {
            findCapture: function(id) {

                var deferred = $q.defer();

                try {
                    var results = _.find(); //do stuff with _
                    deferred.resolve(results);
                } catch (err) {
                    deferred.reject(err);
                }

                //you need to return a promise in order to use then()
                return deferred.promise;

            }
        }
    }
]);

【讨论】:

  • 输出仍然提供undefined,但感谢您已经在未来可能需要修复的东西..
  • @CedricBongaerts 我认为_.find() 不会返回承诺。您需要使用$q。见编辑。
  • 你的代码给了Error: [$injector:unpr] Unknown provider: , $qProvider <- , $q <- captureApi
  • 那我不知道。如果您需要更多帮助,这里是关于 $q 的文档。 docs.angularjs.org/api/ng/service/$q
  • 我错了,它是正确的,我猜是写错了。无论如何,它现在回馈了一个承诺,但价值是未定义的。 Promise {$$state: Object} $$state : Object status : 1 value : undefined __proto__ : Object __proto__ : Object
猜你喜欢
  • 2019-08-19
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 2014-11-29
  • 1970-01-01
相关资源
最近更新 更多