Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I have got TypeError [ERR_INVALID_CALLBACK]: Callback must be a function

Tags:

node.js

I use express-formidable to handle the upload of the form. The normal fields of the form are mounted to req.fields.

The files uploaded by the form are mounted to req.files, and the files are stored in the public/img directory. Then the parameters are verified.

After the verification is passed, the user information is inserted into MongoDB. If it succeeds, it will jump to the home page and display the notification of “registration success”. If it fails (if the user name is occupied), it will jump back to the registration page and display “The user name has been occupied" notification.

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function

const fs = require('fs')
const path = require('path')
const sha1 = require('sha1')
const express = require('express')
const router = express.Router()

const UserModel = require('../models/users')
const checkNotLogin = require('../middlewares/check').checkNotLogin

//Get /register The Page to Create account
router.get('/', checkNotLogin, function (req, res, next){
    res.render('register')
})

router.post('/', checkNotLogin, function(req, res, next){
     const name = req.fields.name
     const gender = req.fields.gender
     const emailaddress = req.fields.emailaddress
     const bio = req.fields.bio
     const avatar = req.files.avatar.path.split(path.sep).pop()
     let password = req.fields.password
     const repassword = req.fields.repassword

     try {
         if (!(name.length >= 1 && name.length <= 10)) {
           throw new Error('Username can not be longer than 10 characters')
         }
         if (['m', 'f', 'x'].indexOf(gender) === -1) {
           throw new Error('Gender only can be m、f or x')
         }
         if(!emailaddress.endsWith('.co.uk')){
             throw new Error('Email Address should be an academic address')
         }
         if (!(bio.length >= 1 && bio.length <= 30)) {
           throw new Error('Please organise your personal description with in 30 characters')
         }
         if (!req.files.avatar.name) {
           throw new Error('Please choose your avator')
         }
         if (password.length < 6) {
           throw new Error('Password should be longer than 6 characters')
         }
         if (password !== repassword) {
           throw new Error('Re-enter the password you set')
         }
       } catch (e) {
         // register fail, delete the avator
         fs.unlink(req.files.avatar.path)
         req.flash('error', e.message)
         return res.redirect('/register')
       }

       // text password encryption
       password = sha1(password)

       // information wait to be enter into database
       let user = {
         name: name,
         password: password,
         emailaddress:emailaddress,
         gender: gender,
         bio: bio,
         avatar: avatar
       }
       // enter user information into database
       UserModel.create(user)
         .then( function (result) {
           user = result.ops[0]
           // delete password,store user information into session
           delete user.password
           req.session.user = user
           //Write into flash
            req.flash('success', 'Account Successfully created')
           // Jump to the home
           res.redirect('/posts')
          })
         .catch(function (e) {
           // Account create failure, delete avator
            fs.unlink(req.files.avatar.path)
           // if username already been use return to register page
           if (e.message.match('duplicate key')) {
             req.flash('error', 'username already be taken')
             return res.redirect('/register')
           }
          next(e)
         })
      })

     module.exports = router

I am not sure where is going wrong I think there are already funcition Any help will be appreciate

This is full error message:

 TypeError [ERR_INVALID_CALLBACK]: Callback must be a function
 at makeCallback (fs.js:137:11)
 at Object.unlink (fs.js:936:14)
 at D:\tttt\CVsWeb\routes\register.js:48:1 express\lib\router\layer.js:95:5)
 at Layer.handle [as handle_request] (D:\tttt\CVsWeb\node_modules\137:13 express\lib\router\layer.js:95:5)
 at next        (D:\tttt\CVsWeb\node_modules\express\lib\router\route.js:express\lib\router\layer.js:95:5)137:13)                                                              137:13)
 at checkNotLogin (D:\tttt\CVsWeb\middlewares\check.js:14:9)      \route.js:112:3)
 at Layer.handle [as handle_request(D:\tttt\CVsWeb\node_modules\express\lib\router\layer.js:95:5)express\lib\router\layer.js:95:5)
at next (D:\tttt\CVsWeb\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (D:\tttt\CVsWeb\node_modules\express\lib\router\route.js:112:3)
  at Layer.handle [as handle_request] (D:\tttt\CVsWeb\node_modules\express\lib\router\layer.js:95:5)
like image 351
JIATAI LI Avatar asked Dec 02 '18 18:12

JIATAI LI


1 Answers

fs.unlink is asynchronous and requires a callback function to be passed as it's second parameter.

Try using fs.unlinkSync(req.files.avatar.path) or insert a function as the second parameter to your unlink fs.unlink(req.files.avatar.path, function(){console.log('Deleted avatar')})

router.post('/', checkNotLogin, function(req, res, next) {
  const name = req.fields.name
  const gender = req.fields.gender
  const emailaddress = req.fields.emailaddress
  const bio = req.fields.bio
  const avatar = req.files.avatar.path.split(path.sep).pop()
  let password = req.fields.password
  const repassword = req.fields.repassword

  try {
    if (!(name.length >= 1 && name.length <= 10)) {
      throw new Error('Username can not be longer than 10 characters')
    }
    if (['m', 'f', 'x'].indexOf(gender) === -1) {
      throw new Error('Gender only can be m、f or x')
    }
    if (!emailaddress.endsWith('.co.uk')) {
      throw new Error('Email Address should be an academic address')
    }
    if (!(bio.length >= 1 && bio.length <= 30)) {
      throw new Error('Please organise your personal description with in 30 characters')
    }
    if (!req.files.avatar.name) {
      throw new Error('Please choose your avator')
    }
    if (password.length < 6) {
      throw new Error('Password should be longer than 6 characters')
    }
    if (password !== repassword) {
      throw new Error('Re-enter the password you set')
    }
  } catch (e) {
    // register fail, delete the avator
    fs.unlinkSync(req.files.avatar.path) //Try this!
    req.flash('error', e.message)
    return res.redirect('/register')
  }

  // text password encryption
  password = sha1(password)

  // information wait to be enter into database
  let user = {
    name: name,
    password: password,
    emailaddress: emailaddress,
    gender: gender,
    bio: bio,
    avatar: avatar
  }
  // enter user information into database
  UserModel.create(user)
    .then(function(result) {
      user = result.ops[0]
      // delete password,store user information into session
      delete user.password
      req.session.user = user
      //Write into flash
      req.flash('success', 'Account Successfully created')
      // Jump to the home
      res.redirect('/posts')
    })
    .catch(function(e) {
      // Account create failure, delete avator
      fs.unlinkSync(req.files.avatar.path) //Also this one
      // if username already been use return to register page
      if (e.message.match('duplicate key')) {
        req.flash('error', 'username already be taken')
        return res.redirect('/register')
      }
      next(e)
    })
})
like image 176
ionizer Avatar answered Nov 08 '22 20:11

ionizer