Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected literal in error position of callback in Vue.JS

I'm trying to follow this tutorial: https://developer.okta.com/blog/2017/09/14/lazy-developers-guide-to-auth-with-vue

But are getting:

 ERROR  Failed to compile with 1 errors    
 error  in ./src/auth.js

  ✘  https://google.com/#q=standard%2Fno-callback-literal  Unexpected literal in error position of callback
  src/auth.js:7:15
        if (cb) cb(true)
                 ^
      ✘  https://google.com/#q=standard%2Fno-callback-literal  Unexpected literal in error position of callback
  src/auth.js:14:17
          if (cb) cb(true)
                   ^
      ✘  https://google.com/#q=standard%2Fno-callback-literal  Unexpected literal in error position of callback
  src/auth.js:17:17
          if (cb) cb(false)
                   ^
      ✘  https://google.com/#q=standard%2Fno-callback-literal  Unexpected literal in error position of callback
  src/auth.js:43:7
        cb({
         ^
      ✘  https://google.com/#q=standard%2Fno-callback-literal  Unexpected literal in error position of callback
  src/auth.js:48:7
        cb({ authenticated: false })
         ^
✘ 5 problems (5 errors, 0 warnings)

Errors:
  5  https://google.com/#q=standard%2Fno-callback-literal

 @ ./src/router/index.js 3:0-26
 @ ./src/main.js
 @ multi ./build/dev-client ./src/main.js

> Listening at http://localhost:8080

The code which fails is the following:

/* globals localStorage */

export default {
  login (email, pass, cb) {
    cb = arguments[arguments.length - 1]
    if (localStorage.token) {
      if (cb) cb(true)
      this.onChange(true)
      return
    }
    pretendRequest(email, pass, (res) => {
      if (res.authenticated) {
        localStorage.token = res.token
        if (cb) cb(true)
        this.onChange(true)
      } else {
        if (cb) cb(false)
        this.onChange(false)
      }
    })
  },

  getToken () {
    return localStorage.token
  },

  logout (cb) {
    delete localStorage.token
    if (cb) cb()
    this.onChange(false)
  },

  loggedIn () {
    return !!localStorage.token
  },

  onChange () {}
}

function pretendRequest (email, pass, cb) {
  setTimeout(() => {
    if (email === '[email protected]' && pass === 'password1') {
      cb({
        authenticated: true,
        token: Math.random().toString(36).substring(7)
      })
    } else {
      cb({ authenticated: false })
    }
  }, 0)
}

So in general it's the if (cb) cb(X).

Trying Google the stuff seems cb(false) and cb(true) aren't allowed, but I'm stuck on how to solve it easily with this example.

This is my login code:

  import auth from '../auth'
  export default {
    data () {
      return {
        email: '[email protected]',
        pass: '',
        error: false
      }
    },
    methods: {
      login () {
        auth.login(this.email, this.pass, loggedIn => {
          if (!loggedIn) {
            this.error = true
          } else {
            this.$router.replace(this.$route.query.redirect || '/')
          }
        })
      }
    }
  }
like image 212
Alfred Balle Avatar asked Jun 08 '18 07:06

Alfred Balle


2 Answers

It seems like it's caused by some code linting tool you use. It thinks that you need to pass error as the first argument for callbacks. You can get around that by changing the function name from cb to something else than cb or callback.

This is how you'd use your login callback with error first:

auth.login(this.email, this.pass, (err, loggedIn) => {
  if (err) {
    // Probably do something with the error
    // LoggedIn isn't really necessary, unless it contains some info about the logged in user
    this.error = true
  } else {
    this.$router.replace(this.$route.query.redirect || '/')
  }
})
like image 147
FINDarkside Avatar answered Nov 03 '22 00:11

FINDarkside


This issue after ESLint approved the no-callback-literal rule.

However there are many many complains about it. I see it being removed or at least modified in the near future.

Currently it matches how error are handled in Express.JS. Actually it incorrectly matches:

callback({foo: 'bar'})

Meanwhile you can disable it by changing your .eslintrc.js so that the rules look like this:

'rules': {
  ...
  'standard/no-callback-literal': 0,
  ...
}
like image 20
adelriosantiago Avatar answered Nov 03 '22 01:11

adelriosantiago