NodeJS 如何使用TypeScript和mongoose生成唯一的slug?

vql8enpb  于 11个月前  发布在  Node.js
关注(0)|答案(1)|浏览(76)

我为此搜索了许多模块,但它不适用于TypeScript,如mongoose-slug-generator和mongoose-slug-plugin

rsl1atfo

rsl1atfo1#

如果你打算使用mongoose-slug-generator,导入或初始化模块如下:

// someModel.ts
...
import mongoose from 'mongoose'

// not import * as slugGenerator from 'mongoose-slug-generator' but
const  slug = require('mongoose-slug-generator')

mongoose.plugin(slug)

字符串
由于上述模块目前不支持TS,必须使用require来代替import。我使用了这种方法,发现它对生成新文档有效,但对编辑/更新现有文档无效。我没有在使用此模块设置解决方案时走得太远,我希望mongoose-slug-generator将继续更新,成为TS友好的模块。
到目前为止,我发现将mongoose.pre('save')中间件与slugify模块结合使用是我正在进行的项目的最有效的选择。
例如

// someModel.ts
import mongoose, { Schema, Document } from 'mongoose'
import slugify from 'slugify'

export interface IPost extends Document {
  id: string
  title: string
  slug: string
  ...
}

const PostSchema: Schema = new Schema<IPost>(
  {
    title: {
      type: String,
      trim: true,
      unique: true,
      index: true,
    },
    slug: {
      type: String,
      unique: true,
    },
    ...
  },
  {
    toJSON: { virtuals: true },
    toObject: { virtuals: true },
    timestamps: true,
  }
)

PostSchema.pre<IPost>('save', async function (next) {
  const post = this as IPost

  if (!post.isModified('title')) return next()

  const slug = slugify(post.title, { lower: true, trim: true })

  post.slug = slug

  return next()
})

...

// someController.ts
...

const updatePost = async (req: Request, res: Response) => {
     const { postId } = req.params

    const { title, ... } = req.body
      
    try {
       // const post = await Post.findOneAndUpdate(filter, update, { new: true }) not working instead:

      let post = await Post.findById(postId)

      post!.title = title
     ...

    await post?.save()  
    
    return res.status(200).json(post)
    } catch (err) {
        if (err instanceof Error) {
            console.error(err.message)
       }
        
  }

相关问题