【问题标题】:Expressjs Using object title as dynamic urlExpressjs 使用对象标题作为动态 url
【发布时间】:2014-10-03 20:13:10
【问题描述】:

我试图弄清楚如何通过标题而不是 ID 来路由我的 GET 单个对象路由参数。我知道body-parser 允许该请求,但不知道如何修改我当前的路由设置以允许这种情况发生。

我的想法是将所有 blogpost_id 更改为 blogpost_title,但我遇到了这个错误。

{
  "message":"Cast to ObjectId failed for value \"Data Cost Upload\" at path \"_id\"",
  "name":"CastError",
  "type":"ObjectId",
  "value":"Data Cost Upload",
  "path":"_id"
}

routes.js:

//Route for individual blogs
    router.route('/blog/:blogpost_id')


    // START GET method blog by ID  
    .get(function(req, res) {



        Blogpost.findById(req.params.blogpost_id, function(err, blogpost) {
            if (err)
                res.send(err);


            //res.json(blogpost);
            res.render('pages/blogpost', {
                blogpost: blogpost
            });
        });
    }) // END GET method blog by ID

    // START PUT method
    .put(function(req, res) {

        Blogpost.findById(req.params.blogpost_id, function(err, blogpost) {

            if (err)
                res.send(err);


            blogpost.title = req.body.title; // update the blog title
            blogpost.author = req.body.author; // update the author name
            blogpost.tagline = req.body.tagline; // update the tagline
            blogpost.content = req.body.content; // update the blog content
            blogpost.category = req.body.category; // update the category 
            blogpost.tags = req.body.tags; //update the tags


            blogpost.save(function(err) {
                if (err)
                    res.send(err);


                res.json({ message: 'Blog updated.' });
            });

        });

    }) // END PUT method

    // START DELETE method
    .delete(function(req, res) {

        Blogpost.remove({
            _id: req.params.blogpost_id

        }, function(err, bear) {
            if (err)
                res.send(err);

            res.json({ message: 'Successfully deleted' });
        });
    });

我如何链接到每个单独的对象:

<div class="blog-content">
                <% blogpost.forEach(function(blogpost) { %>
                    <tr>
                        <td><h2><a href="#" class="blog-title"><%= blogpost.title %></a></h2></td>
                        <td><h3><%= blogpost.date %></h3></td>
                        <td><h3 class="blog-category"><%= blogpost.category %></h3></td>
                        <td><h3 class="blog-tagline"><i><%= blogpost.tagline %></i></h3></td>
                        <td><p><%=: blogpost.content | truncate:800 | append:'...' %></p></td>
                        <td><a href="/blog/<%= blogpost.title %>" class="blog-read-more">Read More</a></td>
                    </tr>
                    <% }); %>
            </div>

点击“阅读全文”的结果网址:http://localhost:8080/blog/Data%20Cost%20Upload

【问题讨论】:

    标签: javascript node.js mongodb express


    【解决方案1】:

    当你收到http://localhost:8080/blog/Data%20Cost%20Upload

    route.get 处理程序使用req.params.blogpost_id = "Data Cost Upload" 调用。

    Blogs.findById 期望第一个参数是 mongoose.Types.ObjectId,但 req.params.blogpost_idstring

    如果您想按标题获取博文,请使用

    function getSearchCriteria(params) {
          return {
              title: params.blogpost_title
          };
    }
    
    function getBlogpostUpdate(body) {
          return {
               title: body.title,
               author: body.author,
               tagline: body.tagline,
               content: body.content,
               category: body.category,
               tags: body.tags
          };
    }
    
    var blogpostsRoute = router.route('/blog/:blogpost_title');
    
    // to manipulate your route params, use router.param
    router.param('blogpost_title', function (req, res, next, blogpost_title) {
        req.params.blogpost_title = blogpost_title.toLowerCase();
        next();
    });
    
    blogpostsRoute 
        .get(function (req, res) {
             var searchCriteria = getSearchCriteria(req.params);
             Blogpost.findOne(searchCriteria, function (err, blogpost) {
                 if (err)
                     res.send(err);
                 res.render('pages/blogpost', {
                     blogpost: blogpost
                 })
             })
         })
         .put(function (req, res) {
             var searchCriteria = getSearchCriteria(req.params);
             var updated = getBlogpostUpdate(req.body)
             Blogpost.findOneAndUpdate(searchCriteria, updated, function (err, updated) {
                 if (err)
                     res.send(err);
    
    
                 res.json({ message: 'Blog updated.' });
             });
         })
         .delete(function (req, res) {
             var searchCriteria = getSearchCriteria(req.params);
             Blogpost.findOneAndRemove(searchCriteria, function (err, removed) {
                 if (err)
                    res.send(err);
    
                 res.json({ message: 'Successfully deleted' });
             });
         });
    

    【讨论】:

    • 嘿@Andrew Volchenko,感谢您的回复。我进行了更改,但遇到了function getBlogpostUpdate(body) 错误:`title = body.title, ^ SyntaxError: Unexpected token = at Module._compile (module.js:439:25) at Object.Module._extensions.. js (module.js:474:10). Also, why is Blogs used instead of Blogpost. I don't have a model attached to a variable Blogs`
    • 嘿@cphill,对不起,犯了愚蠢的错误:(现在检查一下
    • 这很好用。我还有另一个问题,如果我想将路由中的字符设置为小写,我是在路由器参数中还是在其中一个函数中设置 .lowerCase?
    • 嘿@Andrew Volchenko。谢谢!很抱歉再次打扰,但它似乎不起作用。我的负载很长,然后是no data received 页面。这可能是我链接视图的方式吗? &lt;a href="/blog/&lt;%= blogpost.title %&gt;" class="blog-read-more"&gt;Read More&lt;/a&gt;
    • @cphill,是的,对不起,我的错。我忘了在route.param 中打电话给next()。但即使在此更改之后,您也会得到空响应,因为当您尝试获取 http://localhost:port/blog/My%20Awesome%20BlogPost 时,route.param 会将“My Awesome BlogPost”更改为“my Awesome blogpost”,但没有标题为“my awesome blogpost”的博文blogpost' :) 因此,您需要在您的 blogpost 文档中添加额外的字段(例如 blogpost.name),这将是小写的标题,并将 searchCriteria 从 {title: 'smth'} 更改为 {name: 'smth'}
    猜你喜欢
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2012-06-09
    • 2012-11-19
    • 2018-11-24
    相关资源
    最近更新 更多