Search code examples
javascriptvue.jsvuejs2vue-routervue-resource

Can't access Vue from js


I'm trying to create an App with Vue, and Vue-ressource Actually i need to use ressource to made auth system by an API call. But in my Auth.js (that i import into my login.vue) console said he can't read $http of undefined. So apparantly i can't reach 'this' (so vue). Did i missed something ? Or its just a bad use ?

Thank you all

actually my main.js :

import Vue from 'vue'
import VueRouter from 'vue-router'
import VueResource from 'vue-resource'
Vue.use(VueRouter)
Vue.use(VueResource)

import App from './components/App.vue'

import Login from './components/Login.vue'
import Home from './components/Containers.vue'


function requireAuth (to, from, next) {
  if (!auth.loggedIn()) {
    next({
      path: '/',
      query: { redirect: to.fullPath }
    })
  } else {
    next()
  }
}

const router = new VueRouter({
  mode: 'history',
  routes: [
    { path: '/home', name: 'home', component: Home, beforeEnter: requireAuth },
    { path: '/', component: Login },
    { path: '/logout',
      beforeEnter (to, from, next) {
        auth.logout()
        next('/')
      }}
  ]
})

new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

the login.vue

import auth from '../utils/auth'

export default {
  data () {
    return {
      email: '',
      pass: '',
      error: false
    }
  },
  methods: {
    login () {
      auth.login(this.email, this.pass, loggedIn => {
        if (!loggedIn) {
          this.error = true
        } else {
          console.log('good')
          this.$router.replace('/home')
        }
      })
    }
  }
}

and my auth.js where the vue-ressource post is made :

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(() => {
    this.$http.post('localhost:9000/api/login', {email: email, password: pass}).then(response => {
      if (response.status === 200) {
        cb({
          authenticated: true,
          token: Math.random().toString(36).substring(7)
        })
      } else {
        cb({ authenticated: false })
      }
    }, response => {
      console.log('error ' + response.status)
    })
  }, 0)
}

Solution

    1. Replace vue-resource with axios. Easy to do. Vue-resource is not longer maintained by Vue team, so it's bad choice to use it.( https://medium.com/the-vue-point/retiring-vue-resource-871a82880af4#.dwmy5ymjx )

      Axios is widely supported. https://github.com/mzabriskie/axios .

      Nice laracasts about using axios with vue. You will quickly get it. https://laracasts.com/series/learn-vue-2-step-by-step/episodes/18

    2. It is normal that you can't access Vue instance in your auth module. Try to learn more about using this and you will quickly get it 'why?'

    3. To make ajax requests in your auth module, just import axios and use axios.post / axios.get

    Any questions? Comment and I will explain more.