[英]Iam getting "TypeError: Movie.getMovieList is not a function" every time i try to run a object method from a different module
I'am fairly new to JS and i'm making a movie recommendation web app using express and neo4j.我对 JS 相当陌生,我正在使用 express 和 neo4j 制作电影推荐网络应用程序。 I'am facing problems while running an object method for a route.
我在为路由运行对象方法时遇到问题。 Basically I've created a Genre object and invoking a method to get a list of popular movies by specific to that genre which i'm then forwarding to the views.
基本上,我已经创建了一个 Genre 对象并调用了一个方法来获取特定于该类型的流行电影列表,然后我将其转发到视图。
I'am using async and await to handle asynchronous calls, and I've tested every single module separately and they work as intended.我正在使用 async 和 await 来处理异步调用,并且我已经分别测试了每个模块并且它们按预期工作。
I have two classes relevant to this problem - Movie and Genre, and a route to handle requests.我有两个与此问题相关的类 - 电影和流派,以及处理请求的路由。
Genre module:流派模块:
const executeQuery = require('./db/Neo4jApi').executeQuery;
const Movie = require('./Movie');
module.exports = class Genre {
constructor(name) {
this.name = name;
}
async getPopularMovies(limit) {
const response = await executeQuery(
'MATCH(:Genre { name: $name })<-[:IN_GENRE]-(m :Movie)<-[:RATED]-(:User)\
WITH m.imdbId as imdbId, COUNT(*) AS Relevance\
ORDER BY Relevance DESC\
LIMIT $limit\
RETURN collect(imdbId)',
{ name: this.name, limit }
);
return await Movie.getMovieList(response.records[0]._fields[0]);
}
static getGenreList(names) {
const genres = [];
names.forEach(name => genres.push(new Genre(name)));
return genres;
}
static async getAllGenres() {
const response = await executeQuery(
'MATCH (g:Genre) return collect (g.name)'
);
return Genre.getGenreList(response.records[0]._fields[0]);
}
static async test() {
const action = new Genre('Animation');
console.log(await action.getPopularMovies(5));
console.log(Genre.getGenreList(["Action", "Crime", "Thriller"]));
}
}
Movie module:电影模块:
const executeQuery = require('./db/Neo4jApi').executeQuery;
const Person = require('./Person');
const Genre = require('./Genre');
module.exports = class Movie {
constructor(id) {
this.id = id;
}
setPoster() {
let poster_id = "";
for (var i = 0; i < this.id.length; i++) {
if (this.id[i] != '0') {
poster_id = this.id.substring(i);
break;
}
}
this.poster = '/images/' + poster_id + '.jpg';
}
// set details of given imdbid to build object
async getDetails() {
const response = await executeQuery(
'MATCH (m:Movie {imdbId : $id})\
RETURN m.title, m.runtime, m.year, m.plot, m.poster',
{ id: this.id }
);
const fields = response.records[0]._fields;
this.title = fields[0];
this.runtime = fields[1].low;
this.year = fields[2].low;
this.plot = fields[3];
this.setPoster();
}
// return list of movie objects corresponding the given list of imdbIds
// THIS IS THE METHOD THAT IS NOT BEING RECOGNIZED
static async getMovieList(ids) {
const movies = [];
ids.forEach(id => movies.push(new Movie(id)));
for (const movie of movies) await movie.getDetails();
return movies;
}
// return list of genres of movie
async getGenre() {
const response = await executeQuery(
'MATCH (m:Movie {imdbId : $id})-[:IN_GENRE]->(g:Genre)\
RETURN collect(g.name)',
{ id: this.id }
);
return Genre.getGenreList(response.records[0]._fields[0]);
}
// returns average rating of movie (out of 5)
async getAvgRating() {
const response = await executeQuery(
'MATCH (:Movie {imdbId : $id})<-[r:RATED]->(:User)\
RETURN AVG(r.rating)',
{ id: this.id }
);
return response.records[0]._fields[0].toFixed(2);
}
// return director/s of movie
async getDirector() {
const response = await executeQuery(
'MATCH (m:Movie {imdbId : $id})<-[:DIRECTED]-(d:Director)\
RETURN collect(d.name)',
{ id: this.id }
);
return Person.getPersonList(response.records[0]._fields[0]);
}
// returns cast of movie
async getCast() {
const response = await executeQuery(
'MATCH (m:Movie {imdbId : $id})<-[:ACTED_IN]-(a:Actor)\
RETURN collect(a.name)',
{ id: this.id }
);
return Person.getPersonList(response.records[0]._fields[0]);
}
// returns movies similar to this movie
async getSimilar(limit) {
const response = await executeQuery(
'MATCH (curr :Movie { imdbId: $id })-[:IN_GENRE]->(g:Genre)<-[:IN_GENRE]-(sim :Movie)\
WITH curr, sim, COUNT(*) AS commonGenres\
OPTIONAL MATCH(curr)<-[: DIRECTED]-(d:Director)-[:DIRECTED]-> (sim)\
WITH curr, sim, commonGenres, COUNT(d) AS commonDirectors\
OPTIONAL MATCH(curr)<-[: ACTED_IN]-(a: Actor)-[:ACTED_IN]->(sim)\
WITH curr, sim, commonGenres, commonDirectors, COUNT(a) AS commonActors\
WITH sim.imdbId AS id, (3 * commonGenres) + (5 * commonDirectors) + (2 * commonActors) AS Similarity\
ORDER BY Similarity DESC\
LIMIT $limit\
RETURN collect(id)',
{ id: this.id, limit }
);
return await Movie.getMovieList(response.records[0]._fields[0]);
}
// returns all time popular movie
static async getPopularMovies(limit) {
const response = await executeQuery(
'MATCH (m :Movie)<-[:RATED]-(:User)\
WITH m.imdbId as imdbId, COUNT(*) AS Relevance\
ORDER BY Relevance DESC\
LIMIT $limit\
RETURN collect(imdbId)',
{ limit }
);
return await Movie.getMovieList(response.records[0]._fields[0]);
}
// returns popular movies of given year
static async getPopularMoviesByYear(year, limit) {
const response = await executeQuery(
'MATCH(m :Movie {year : $year})<-[:RATED]-(:User)\
WITH m.imdbId as imdbId, COUNT(*) AS Relevance\
ORDER BY Relevance DESC\
LIMIT $limit\
RETURN collect(imdbId)',
{ year, limit }
);
return await Movie.getMovieList(response.records[0]._fields[0]);
}
static async getYears() {
const response = await executeQuery(
'MATCH (m:Movie)\
WITH DISTINCT m.year AS year ORDER BY year DESC\
RETURN COLLECT(year)'
);
return response.records[0]._fields[0];
}
static async test() {
}
}
Route :路线 :
const express = require('express');
const router = express.Router();
const Genre = require('../models/Genre');
const Movie = require('../models/Movie');
// get popular movies by all genre
router.get('/', async (req, res) => {
const allGenrePopular = await Movie.getPopularMovies(25);
const genres = await Genre.getAllGenres();
res.render('genre-list', {
title: 'All Genres',
header: 'Popular Movies: All Genres',
movies: allGenrePopular,
genres
});
});
// get popular movies by genre
router.get('/:genre?', async (req, res) => {
const genre = new Genre(req.params.genre);
const popularMovies = await genre.getPopularMovies(25);// error originated here
const genres = await Genre.getAllGenres();
res.render('genre-list', {
title: `${genre.name}`,
header: `Popular Movies: ${genre.name}`,
movies: popularMovies,
genres
});
});
module.exports = router;
But i keep getting this error:但我不断收到此错误:
(node:10272) UnhandledPromiseRejectionWarning: TypeError: Movie.getMovieList is not a function
at Genre.getPopularMovies (C:\Users\Admin\Desktop\project\newmd\models\Genre.js:19:28)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:10272) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:10272) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the
Node.js process with a non-zero exit code.
The problem is originating in the getMovieList() function in movie module, but i've tested it seperately times and it works fine.问题源于电影模块中的 getMovieList() 函数,但我已经对其进行了多次测试,并且运行良好。
Any suggestion to improve my code is welcome.欢迎任何改进我的代码的建议。
Looks like you have a circular dependency issue here, which means your Genre
class requires the Movie
class and vice versa.看起来您在这里有一个循环依赖问题,这意味着您的
Genre
类需要Movie
类,反之亦然。
Remove one inclusion which you feel is not necessary (either Genre
inclusion from the Movie
class (or) Movie
inclusion form the Genre
class) and this issue will be resolved.删除您认为没有必要的一个包含(来自
Movie
类的Genre
包含(或)来自Genre
类的Movie
包含),此问题将得到解决。
Hope this helps!希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.