Как устранить проблему с серверной частью Node Js, выполняющей только первый контроллер?

#node.js #angular #typescript #express #mean-stack

#node.js #угловатый #машинописный текст #экспресс #означает-стек

Вопрос:

На моем сайте обзора книг в опции поиска пользователь может искать книги либо по author названию, либо по genre . Для них у меня есть отдельные функции в search.service.ts ниже. В серверной части также есть отдельные контроллеры. Но во время поиска он выполняет только первый контроллер, он не выполняет второй контроллер, даже если маршрут направлен к нему.

Вот search.service.ts функции,

 getPostsByAuthor(author: string) {
  this.http.get<{message: string, posts: any, maxPosts: number }>(BACKEND_URL   'api/search/'   author)
  .pipe(map((postData) => {
    console.log(postData);
    return { posts: postData.posts.map((post) => {
      return {
        title: post.title,
        content: post.content,
        author: post.author,
        genre: post.genre,
        id: post._id,
        imagePath: post.imagePath,
        creator: post.creator
      };
    }),
    maxPosts: postData.maxPosts};
  }))
  .subscribe(transformedPostsData => {
    this.posts = transformedPostsData.posts;
    return this.posts;
  });
}

getPostsByGenre(genre: string) {
  this.http.get<{message: string, posts: any, maxPosts: number }>(BACKEND_URL   'api/search/'   genre)
  .pipe(map((postData) => {
    console.log('Genre_');
    console.log(postData);
    return { posts: postData.posts.map((post) => {
      return {
        title: post.title,
        content: post.content,
        author: post.author,
        genre: post.genre,
        id: post._id,
        imagePath: post.imagePath,
        creator: post.creator
      };
    }),
    maxPosts: postData.maxPosts};
  }))
  .subscribe(transformedPostsData => {
    this.posts = transformedPostsData.posts;
    return this.posts;
  });
}
  

Маршрут в app.js ,

 app.use('/api/search', searchRoutes);
  

search.js В папке route,

 const express = require('express');

const router = express.Router();

const SearchController = require('../controllers/search');

router.get("/:author", SearchController.getPostsByAuthor);

router.get("/:Genre", SearchController.getPostsByGenre);

module.exports = router;
  

Здесь последовательно приведены контроллеры,

 const Post = require('../models/post');
const User = require('../models/user');

exports.getPostsByAuthor = (req, res, next) => {
  let maxPosts = 10;
  Post.find({ author: req.params.author }).then(posts => {
    if(posts) {
      res.status(200).json({
        posts,
        message: "Post was successful",
        max: maxPosts
      });
    } else {
      res.status(500).alert('Not Found, double check the spelling').json({
        message: "Failed to get User Post"
      });
    }
  });
}

exports.getPostsByGenre = (req, res, next) => {
  let maxPosts = 10;
  Post.find({ genre: req.params.genre }).then(posts => {
    if(posts) {
      res.status(200).json({
        posts,
        message: "Post  weirdo successful",
        max: maxPosts
      });
    } else {
      res.status(500).json({
        message: "Failed to get User Post"
      });
    }
  });
}
  

Он всегда запускает первый, что означает getPostsByAuthor , что он никогда не запускает второй.

Я проверил, изменив порядок, когда я поставил getPostsByGenre на первую позицию, тогда это было запущено и getPostsByAuthor не запускалось, так как оно было размещено вторым по порядку.

Контроллер, расположенный в первой позиции по порядку, возвращает данные идеально, это означает, что маршрут достигает controller файла.

Я не понимаю, в чем проблема. Не нашел подобных вопросов в SO.

Я все еще новичок в разработке со средним стеком, минимум подсказок означал бы большую помощь. Спасибо.

Комментарии:

1. в exports.getPostsByGenre функции вы должны использовать User.find вместо Post.find ?

2. Спасибо за ваш ответ. Я только что попробовал, это не сработало. :-/

3. Если я правильно понимаю, вы хотите, чтобы были выполнены оба маршрута, getPostsByAuthor и getPostsByGenre ?

4. Нет, пользователь выполняет поиск либо по автору, либо по жанру. У обоих есть отдельные кнопки с отдельными событиями, которые запускают отдельные функции, но не одновременно.

Ответ №1:

Способ, которым вы пытаетесь добиться маршрутизации, неправильный.

Когда клиент делает GET запросы на маршрутизацию /api/search , express будет проверять, определен ли GET маршрут для пути. В данном случае он выполнит первый найденный маршрут router.get("/:author", SearchController.getPostsByAuthor) (который вы смонтировали первым).

Это связано с тем, что промежуточные ПРОГРАММЫ монтируются как stack, сначала выполняется промежуточное программное обеспечение, затем следующее и так далее.

Вам нужно будет определить два разных маршрута, поскольку они являются GET запросами к двум разным ресурсам, что-то вроде:

 const SearchController = require('../controllers/search');

router.get("/author/:author", SearchController.getPostsByAuthor);

router.get("/genre/:Genre", SearchController.getPostsByGenre);

app.use('/api/search', searchRoutes);
  

Затем вы можете вызвать, как:

 api/search/author/someName

api/search/genre/someGenre
  

Комментарии:

1. Большое вам спасибо, сэр, за подробное объяснение. Это помогло мне многому научиться, а также исправило ситуацию.