簡體   English   中英

需要幫助弄清楚為什么從 mongoose 模式調用方法在我的 node.js 應用程序的一部分工作正常,但在其他地方失敗

[英]Need help figuring out why calling methods from a mongoose schema works fine in one part of my node.js app, but fails elsewhere

我創建了以下用戶模式,包括兩種方法:getSnapshot() getLastTweetId()

用戶.js

    const mongoose = require('mongoose')
    const getLastTweetId = require('../utilities/getLastTweetId')
    const getFollowers = require('../utilities/getFollowers')
    
    const userSchema = new mongoose.Schema({
        twitterId: {
            type: String,
            required: true
        },
        screenName: {
            type: String    
        },
        snapshots: {
          type: [snapshotSchema],
          default: []
        },
        createdAt: {
            type: Date
        },
    })
    
    userSchema.method('getSnapshot', async function () {
      const { user, snapshot } = await getFollowers({user: this})
      await user.save()
      return snapshot
    })
    
    userSchema.method('getLastTweetId', async function () {
      const tweetId = await getLastTweetId({user: this})
      return tweetId
    })
    
    const User = mongoose.model('User', userSchema)
    
    module.exports = User

當我在 passport.js 中定義一個用戶實例時,我可以毫無問題地對用戶調用 getSnapshot()。 (見下文)

護照.js

    const passport = require('passport')
    const mongoose = require('mongoose')
    const needle = require('needle')
    const { DateTime } = require('luxon')
    const User = mongoose.model('User')
    
    // Setup Twitter Strategy
    passport.use(new TwitterStrategy({
        consumerKey: process.env.TWITTER_CONSUMER_API_KEY,
        consumerSecret: process.env.TWITTER_CONSUMER_API_SECRET_KEY,
        callbackURL: process.env.CALLBACK_URL,
        proxy: trustProxy
      },
      async (token, tokenSecret, profile, cb) => {
        const twitterId = profile.id
        const screenName = profile.screen_name
    
        const existingUser = await User.findOne({ twitterId })
        if (existingUser) {
          // Track if this is a new login from an existing user
          if (existingUser.screenName !== screenName) {
              existingUser.screenName = screenName
              await existingUser.save()
          }
          // we already have a record with the given profile ID
          cb(undefined, existingUser)
        } else {
          // we don't have a user record with this ID, make a new record
          const user = await new User ({
            twitterId ,
            screenName,
          }).save()
          **user.getSnapshot()**
          cb(undefined, user)
        }
      }
    )

但是,當我在 tweet.js 中的用戶實例上調用 getLastTweetId() 時,我在終端中收到以下錯誤: TypeError: user.getLastTweetId is not a function

然后我的應用程序崩潰了。

tweets.js

    const express = require('express')
    const mongoose = require('mongoose')
    const User = mongoose.model('User')
    const Tweet = mongoose.model('Tweet')
    const { DateTime } = require('luxon')
    const auth = require('../middleware/auth')
    const requestTweets = require('../utilities/requestTweets')
    
    const router = new express.Router()
    
    const getRecentTweets = async (req, res) => {
        const twitterId = req.user.twitterId
        const user = await User.find({twitterId})
    
        *const sinceId = user.getLastTweetId()*
    
        let params = {
          'start_time': `${DateTime.now().plus({ month: -2 }).toISO({ includeOffset: false })}Z`,
          'end_time': `${DateTime.now().toISO({ includeOffset: false })}Z`,
          'max_results': 100,
          'tweet.fields': "created_at,entities"
        }
      
        if (sinceId) {
         params.since_id = sinceId
        }
    
        let options = {
          headers: {
            'Authorization': `Bearer ${process.env.TWITTER_BEARER_TOKEN}`
          }
        }
        const content = await requestTweets(twitterId, params, options)
        const data = content.data
    
        const tweets = data.map((tweet) => (
          new Tweet({
            twitterId,
            tweetId: tweet.id,
            text: tweet.text,
          })
        ))
        tweets.forEach(async (tweet) => await tweet.save())
    }
    
    // Get all tweets of one user either since last retrieved tweet or for specified month
    router.get('/tweets/user/recent', auth, getRecentTweets)
    
    module.exports = router

我真的很感激一些支持來弄清楚這里發生了什么。 謝謝你的包容!

我的第一個猜測是用戶實例沒有在 tweets.js 中正確創建,但后來我通過日志消息驗證用戶實例是我期望它在 passport.js 和 tweets.js 中的

我的第二個猜測是問題是數據庫中的用戶實例是在我將新方法添加到模式之前創建的,但是刪除並重新實例化數據庫中的整個集合沒有任何改變。

接下來,我開始檢查問題是否與實例化架構本身或只是導入它有關,它似乎是后者,因為當我在 passport.js 中調用 getLastTweetId 時它也有效,當我在 tweets.js 中調用 getSnapshot() 時它也失敗了。

這就是我卡住的地方,因為據我所知,我在兩個文件中要求用戶 model 的方式完全相同。

即使當我在任一文件中打印 User.schema.methods 時,它也會顯示以下內容:

[0] {
[0] getSnapshot: [AsyncFunction (anonymous)],
[0] getLastTweetId: [AsyncFunction (anonymous)]
[0] }

看起來我對錯誤的第一個猜測是正確的,而且我只是草率地驗證了我是否正確地實例化了用戶。

   const user = await User.find({twitterId})

上面的行返回了一組用戶。

相反,我應該打電話給:

   const user = await User.findOne({twitterId})

一開始我沒有檢測到這個錯誤,因為記錄一個只包含一個 object 的數組看起來幾乎和記錄 object 本身一樣,我只是忽略了方括號。

更改該單行修復它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM