my code in github, but I didn’t upload the latest version:
https://github.com/godzillalogan/markdownblog
I use node.js and express.js framework. Database use mongoDB.
I am using the package Imgur and dotenv, try to upload image to imgur.
But I encounter some bug:
bug:
App is running on http://localhost:3000
mongodb connected!
TypeError: Cannot read property 'then' of undefined
at Promise (D:Githubmarkdownbloghelpersfile-helpers.js:26:7)
at new Promise (<anonymous>)
at imgurFileHandler (D:Githubmarkdownbloghelpersfile-helpers.js:23:10)
at router.put (D:Githubmarkdownblogroutesmodulesadmin.js:115:26)
at process._tickCallback (internal/process/next_tick.js:68:7)
D:Githubmarkdownblognode_modulesimgur-node-apilibimgur.js:34
_cb(null, body);
^
TypeError: _cb is not a function
at Request._callback (D:Githubmarkdownblognode_modulesimgur-node-apilibimgur.js:34:9)
at Request.self.callback (D:Githubmarkdownblognode_modulesrequestindex.js:142:22)
at Request.emit (events.js:182:13)
at Request.<anonymous> (D:Githubmarkdownblognode_modulesrequestindex.js:856:14)
at Request.emit (events.js:187:15)
at IncomingMessage.<anonymous> (D:Githubmarkdownblognode_modulesrequestindex.js:808:12)
at IncomingMessage.emit (events.js:187:15)
at endReadableNT (_stream_readable.js:1094:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
[nodemon] app crashed - waiting for file changes before starting...
Here is my code:
app.js:
const path = require('path') // 引入 path 套件
const express = require('express')
const session = require('express-session')
const bodyParser = require('body-parser') //新版express以內建body-parser
const { engine } = require('express-handlebars');
const flash = require('connect-flash')
if (process.env.NODE_ENV !== 'production') { //要放在const routes = require('./routes')前面
require('dotenv').config()
}
const routes = require('./routes')
const app = express()
const PORT = process.env.PORT || 3000
const methodOverride = require('method-override') // 載入 method-override
//others code............
helpers/file-helpers.js:
const fs = require('fs') // 引入 fs 模組, fs 模組是 Node.js 提供專門來處理檔案的原生模組
//載入 imgur 套件
const imgur = require('imgur-node-api')
const IMGUR_CLIENT_ID = process.env.IMGUR_CLIENT_ID
console.log('IMGUR_CLIENT_ID:',IMGUR_CLIENT_ID)
imgur.setClientID(IMGUR_CLIENT_ID)
const localFileHandler = file => { // file 是 multer 處理完的檔案
return new Promise((resolve, reject) => {
if (!file) return resolve(null)
const fileName = `upload/${file.originalname}`
return fs.promises.readFile(file.path)
.then(data => fs.promises.writeFile(fileName, data))
.then(() => resolve(`/${fileName}`))
.catch(err => reject(err))
})
}
const imgurFileHandler = file => {
return new Promise((resolve, reject) => {
if (!file) return resolve(null)
return imgur.upload(file.path)
.then(img => {
// resolve(img?.link || null) // 檢查 img 是否存在
resolve(img ? img.link : null)
})
.catch(err => reject(err))
})
}
module.exports = {
localFileHandler,
imgurFileHandler //img
}
routes/modules/admin:
const express = require('express')
const router = express.Router()
const Article = require('../../models/article');
const Category = require('../../models/category');
const User = require('../../models/user');
const Contact = require('../../models/contact');
const upload = require('../../middleware/multer') // 載入 multer
const { imgurFileHandler } = require('../../helpers/file-helpers') // 將 file-helper 載進來
////others code....
//edit user
router.put('/users/:id', upload.single('avatar'), async (req, res)=>{
try{
console.log('有到edit user嗎')
const _id = req.params.id
const { name,avatar,introduction } = req.body
const { file } = req // 把檔案取出來
const user = await User.findOne({ _id})
const filePath = await imgurFileHandler(file) // 把檔案傳到 file-helper 處理
user.name = name
// user.cover = filePath || user.cover
user.avatar = filePath || user.avatar
user.introduction = introduction
await user.save()
res.redirect('/about')
}catch(e){
console.log(e)
res.redirect(`/admin/users`)
}
// const {title,description,markdown} = req.body //和new一樣才能將markdown轉成html
// Article.create({...req.body})
// res.redirect('/')
////others code....
})
What I have try:
I think it is about promise problem, and localFileHandler in helpers/file-helpers.js is work successful , but why imgurFileHandler in helpers/file-helpers.js is not work .
Thank you for your help.
2
Answers
I move it from helpers/file-helpers.js to routes/modules/admin.js. And the way is success. But I think there would have another better way.
routes/modules/admin.js
I add Imgur to the route in create article,edit article and edit user.
routes/modules/admin.js
It’s probably because imgur.upload() dosent support promises and you should pass a callback as a second argument to the function like this :