title: Formatting authentication request object from VueJS properly
body: <p>I have a VueJS/Vuex frontend consuming an express/postgres api. </p>
  
  <p>In Postman, both registration and login work with a request like:</p>
  
  <pre><code>{ "user": { "email": "user@gmail", "password":...}}
  </code></pre>
  
  <p>From the Vue app, registration works as expected, but for login, instead of sending a request object like </p>
  
  <pre><code>{ "user": { "email": "user@gmail", "password":...}}
  </code></pre>
  
  <p>, which is what the api is expecting, it is sending only, </p>
  
  <pre><code>{ "email": "user@gmail", "password":...}
  </code></pre>
  
  <p>This results in the api throwing: </p>
  
  <blockquote>
    <p>TypeError: Cannot read property 'email' of undefined</p>
  </blockquote>
  
  <p>Here is my Login component:</p>
  
  <pre><code>&lt;template&gt;
    &lt;div class="ui stackable three column centered grid container"&gt;
      &lt;div class="column"&gt;
        &lt;h2 class="ui dividing header"&gt;Log In&lt;/h2&gt;
  
        &lt;Notification
          :message="notification.message"
          :type="notification.type"
          v-if="notification.message"
        /&gt;
  
        &lt;form class="ui form" @submit.prevent="login"&gt;
          &lt;div class="field"&gt;
            &lt;label&gt;Email&lt;/label&gt;
            &lt;input type="email" name="email" v-model="email" placeholder="Email" required&gt;
          &lt;/div&gt;
  
          &lt;div class="field"&gt;
            &lt;label&gt;Password&lt;/label&gt;
            &lt;input type="password" name="password" v-model="password" placeholder="Password" required&gt;
          &lt;/div&gt;
  
          &lt;button class="fluid ui primary button"&gt;LOG IN&lt;/button&gt;
  
          &lt;div class="ui hidden divider"&gt;&lt;/div&gt;
        &lt;/form&gt;
  
        &lt;div class="ui divider"&gt;&lt;/div&gt;
  
        &lt;div class="ui column grid"&gt;
          &lt;div class="center aligned column"&gt;
            &lt;p&gt;
              Don't have an account? &lt;router-link to="/signup"&gt;Sign Up&lt;/router-link&gt;
            &lt;/p&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  import Notification from '@/components/Notification'
  export default {
    name: 'LogIn',
    components: {
      Notification
    },
    data () {
      return {
        email: '',
        password: '',
        notification: {
          message: '',
          type: ''
        }
      }
    },
    // beforeRouteEnter (to, from, next) {
    //   const token = localStorage.getItem('tweetr-token')
  
    //   return token ? next('/') : next()
    // },
    methods: {
      login () {
        this.$store
          .dispatch('login', {
            email: this.email,
            password: this.password
          })
          .then(() =&gt; {
            console.log(this.$store.user)
            // redirect to user home
            this.$router.push('/')
          })
          .catch(error =&gt; console.log(error))
      }
    }
  }
  &lt;/script&gt;
  </code></pre>
  
  <p>And this is my store.js:</p>
  
  <pre><code>import Vue from 'vue'
  import Vuex from 'vuex'
  import axios from 'axios'
  
  // import SubscriptionsService from './services/SubscriptionsService'
  
  Vue.use(Vuex)
  const VUE_APP_ROOT_API = 'http://localhost:8000'
  
  export default new Vuex.Store({
    state: {
      status: '',
      user: JSON.parse(localStorage.getItem('user'))
    },
    mutations: {
      auth_request (state) {
        state.status = 'Signing in...'
      },
      set_user (state, user) {
        state.user = user
        localStorage.setItem('user', JSON.stringify(user))
        console.log(user)
      },
      auth_success (state) {
        state.status = 'success'
      },
      auth_error (state) {
        state.status = 'Invalid credentials'
      },
      logout (state) {
        state.status = ''
        state.user = null
        localStorage.removeItem('user')
      }
    },
    actions: {
      register ({ commit }, user) {
        return new Promise((resolve, reject) =&gt; {
          commit('auth_request')
          console.log(process.env.VUE_APP_ROOT_API)
          axios({ url: VUE_APP_ROOT_API + '/api/auth', data: user, method: 'POST' })
            .then(async resp =&gt; {
              const user = resp.data.user
              commit('auth_success')
              commit('set_user', user)
              resolve(resp)
            })
            .catch(err =&gt; {
              commit('auth_error', err)
              localStorage.removeItem('token')
              reject(err)
            })
        })
      },
      login ({ commit }, user) {
        return new Promise((resolve, reject) =&gt; {
          commit('auth_request')
          console.log(user);
          axios({ url: VUE_APP_ROOT_API + '/api/auth/login', data: user, method: 'POST' })
            .then(resp =&gt; {
              const user = resp.data.user
              // console.log(user)
              // console.log(resp)
              commit('auth_success')
              commit('set_user', user)
              resolve(resp)
            })
            .catch(err =&gt; {
              commit('auth_error')
              commit('logout')
              reject(err)
            })
        })
      },
      logout ({ commit }) {
        return new Promise((resolve) =&gt; {
          commit('logout')
          localStorage.removeItem('token')
          delete axios.defaults.headers.common['authorization']
          resolve()
        })
      }
    },
    getters: {
      isAuthenticated: state =&gt; !!state.user,
      authStatus: state =&gt; state.status,
      user: state =&gt; state.user
    }
  })
  </code></pre>
  
  <p>for comparison, here is my working SignUp component:</p>
  
  <pre><code>&lt;template&gt;
    &lt;div class="ui stackable three column centered grid container"&gt;
      &lt;div class="column"&gt;
        &lt;h2 class="ui dividing header"&gt;Sign Up, it's free!&lt;/h2&gt;
  
        &lt;form class="ui form" @submit.prevent="signup"&gt;
  
          &lt;div class="field"&gt;
            &lt;label&gt;Username&lt;/label&gt;
            &lt;input type="username" name="username" v-model="username" placeholder="Username"&gt;
          &lt;/div&gt;
  
          &lt;div class="field"&gt;
            &lt;label&gt;Email&lt;/label&gt;
            &lt;input type="email" name="email" v-model="email" placeholder="Email"&gt;
          &lt;/div&gt;
  
          &lt;div class="field" &gt;
            &lt;label&gt;Password&lt;/label&gt;
            &lt;input type="password" name="password" v-model="password" placeholder="Password"&gt;
          &lt;/div&gt;
  
          &lt;button class="fluid ui primary button"&gt;SIGN UP&lt;/button&gt;
  
          &lt;div class="ui hidden divider"&gt;&lt;/div&gt;
        &lt;/form&gt;
  
        &lt;div class="ui divider"&gt;&lt;/div&gt;
  
        &lt;div class="ui column grid"&gt;
          &lt;div class="center aligned column"&gt;
            &lt;p&gt;
              Got an account? &lt;router-link to="/login"&gt;Log In&lt;/router-link&gt;
            &lt;/p&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  
  export default {
    name: 'SignUp',
    data () {
      return {
        email: '',
        password: '',
        username: '',
        notification: {
          message: '',
          type: ''
        }
      }
    },
    methods: {
      signup: function () {
        let data = {
          user: {
            email: this.email,
            password: this.password,
            username: this.username
          }
        }
        this.$store.dispatch('register', data)
          .then(() =&gt; this.$router.push('/'))
          .catch(err =&gt; console.log(err))
      },
    }
  }
  &lt;/script&gt;
  </code></pre>
  
  <p>How do I format the request object to match what the api expects?</p>