RangeError,语法错误:正则表达式无效

时间:2018-07-29 05:46:26

标签: javascript angularjs node.js mongodb mongoose

嗨,

我一直在平均堆栈上关注this tutorial

但是,经过第7步后,我发现自己遇到了无法解决的错误。

当尝试获取“ / shows /:id” 路线时,Chrome偶然遇到了一个错误循环,却无能为力:

RangeError: Maximum call stack size exceeded
SyntaxError: Invalid regular expression: /^\d+$/: Stack overflow

在冻结相同动作时,Mozilla会给出以下错误消息:

[invalid object] <div ng-view="" class="ng-scope">

由于执行了教程的每个步骤并检查了任何错误,因此我不确定应该在此处复制哪些代码示例。

但是,我使用了TMDB api而不是本教程建议的api,并进行了一些调整。

这是服务器和路由代码:

var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
var async = require('async');
var request = require('request');
var xml2js = require('xml2js');
var _ = require('lodash');

// MONGOOSE
var showSchema = new mongoose.Schema({
  _id: Number,
  name: String,
  createdBy: String,
  nextEpisodeToAir: String,
  airsTime: String,
  firstAired: Date,
  genre: [String],
  network: String,
  overview: String,
  rating: Number,
  ratingCount: Number,
  status: String,
  poster: String,
  subscribers: [{
    type: mongoose.Schema.Types.ObjectId, ref: 'User'
  }],
  seasonsCount: Number,
  episodesCount: Number,
  episodes: [{
    season: Number,
    episodeNumber: Number,
    episodeName: String,
    firstAired: Date,
    overview: String
  }]
});

var userSchema = new mongoose.Schema({
  email: {
    type: String,
    unique: true
  },
  password: String
});

userSchema.pre('save', function(next) {
  var user = this;
  if (!user.isModified('password')) return next();
  bcrypt.genSalt(10, function(err, salt) {
    if (err) return next(err);
    bcrypt.hash(user.password, salt, function(err, hash) {
      if (err) return next(err);
      user.password = hash;
      next();
    });
  });
});

// compare passwords
userSchema.methods.comparePassword = function(candidatePassword, cb) {
  bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
    if (err) return cb(err);
    cb(null, isMatch);
  });
};

// models
var User = mongoose.model('User', userSchema);
var Show = mongoose.model('Show', showSchema);

// connect
mongoose.connect('mongodb://localhost:27017/shows', {useNewUrlParser: true});

var app = express();

app
    .set('port', process.env.PORT || 3000)
    .use(logger('dev'))
    .use(bodyParser.json())
    .use(bodyParser.urlencoded({extended: true}))
    .use(cookieParser())
    .use(express.static(path.join(__dirname, 'public')));


// REST routes
app.get('/api/shows', function(req, res, next) {
  var query = Show.find();
  if (req.query.genre) {
    query.where({genre: req.query.genre});
  } else if (req.query.alphabet) {
    query.where({name: new RegExp('^' + '[' + req.query.alphabet + ']', 'i')});
  } else {
    query.limit(12);
  }
  query.exec(function(err, shows) {
    if (err) return next(err);
    res.send(shows);
  });
});

app.get('/api/shows/:id', function(req, res, next) {
  Show.findById(req.params.id, function(err, show) {
    if (err) return next(err);
    res.send(show);
  });
});

app.post('/api/shows', function(req, res, next) {
  //themoviedb.org API
  const apiKey = 'c230f35fe557299c704ef84fe35aa8fa';
  const urlTMDB = 'https://api.themoviedb.org/3/';  
/*
    1. Get the Show ID given the Show Name and pass it on to the next function.
    2. Get the show information using the Show ID from previous step and pass the new show object on to the next function.
    3. Convert the poster image to Base64, assign it to show.poster and pass the show object to the final callback function.
    4. Save the show object to database.
*/
    async.waterfall([
      function(cb) {
        // Get the show ID
 
        let options = {
          method: 'GET',
          url: urlTMDB + 'search/tv',
          qs: {
            query: req.body.showName,
            api_key: apiKey
          },
          body: '{}'
        };
    
        request(options, function(err, res, body) {
          if (err) throw new Error(err);
          let data = JSON.parse(body);
          // console.log(data.total_results);
          if(data.total_results === 0) {
            return req.res.status(404).send({message: req.body.showName + ' was not found.'});
          }
          let seriesId = data.results[0].id;
          // console.log('id:' + seriesId);
          cb(err, seriesId);
        });
      },
      function(seriesId, cb) {

        // Get Show info
        let options = {
          method: 'GET',
          url: urlTMDB + 'tv/' + seriesId,
          qs: {api_key: apiKey},
          body: '{}'
        }

        request(options, function(err, res, body) {
          if (err) throw new Error(err);
          let data = JSON.parse(body);
          // Creating genres array because don't know how to fix this inline
          let genres = [];
          data.genres.forEach(g => {
            genres.push(g.name);
          });
          let show = new Show({
            _id: data.id,
            name: data.original_name,
            createdBy: data.created_by,
            nextEpisodeToAir: data.next_episode_to_air,
            airsTime: data.episode_run_time,
            firstAired: data.first_air_date,
            genre: genres,
            network: data.networks[0].name,
            overview: data.overview,
            rating: data.vote_average,
            ratingCount: data.vote_count,
            status: data.status,
            poster: 'https://image.tmdb.org/t/p/w500/' + data.poster_path,
            seasonsCount: data.number_of_seasons,
            episodesCount: data.number_of_episodes
          });
          // console.log(show);
          cb(err, seriesId, show);
        });
      },
      function(err, show) {
        show.save(function(err) {
          if (err) {
            if (err.code == 11000) {
              return res.status(409).send({message: show.name + ' already exists.'});
            }
            return next(err);
          }
          res.sendStatus(200);
        });
      }
    ]);
  });

// handles bad routes and redirect
// using * (wild card)
// KEEP THIS ATER ALL OTHER ROUTES

app.get('*', function(req, res) {
  res.redirect('/#' + req.originalUrl);
});



// Stack trace of errors
app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send({message: err.message});
});


app.listen(app.get('port'), function() {
  console.log('Express server listening on port ' + app.get('port'));
});

这是我的详细信息控制器:

angular.module('MyApp')
    .controller('DetailCtrl', ['$scope', '$rootScope', '$routeParams', 'Show', 'Subscription', 
        function($scope, $rootScope, $routeParams, Show, Subscription) {
            Show.get({_id: $routeParams.id}, function(show) {
                $scope.show = show;

                $scope.isSubscribed = function() {
                    return $scope.show.subscribers.indexOf($rootScope.currentUser._id) !== -1;
                };

                $scope.subscribe = function() {
                    Subscription.subscribe(show).success(function() {
                        $scope.show.subscribers.push($rootScope.currentUser._id);
                    });
                };

                $scope.unsubscribe = function() {
                    Subscription.unsubscribe(show).success(function() {
                        let index = $scope.show.subscribers.indexOf($rootScope.currentUser._id);
                        $scope.show.subscribers.splice(index, 1);
                    });
                };


                
                $scope.nextEpisode = show.episodes.filter(function(episode0) {
                    return new Date(episode.firstAired) > new Date();
                })[0];


            });
    }]);

希望此问题更加清晰:/ 谢谢大家的帮助!

1 个答案:

答案 0 :(得分:0)

圣牛,我觉得很愚蠢。

mozilla错误消息打扰了我,因为它指向了视图代码。 在检查模块代码时,我发现我在访问 / shows /:id 时应使用的视图名称中打了一个错字。

现在一切正常。对不起,麻烦:)