Home > Mobile >  Call Laravel 8 login API with VueJS 3 App
Call Laravel 8 login API with VueJS 3 App

Time:11-10

I'm new to programming with VueJs, and I'm making a simple app that allows the user to login and once authenticated show a list of services in a table.

I manage authentication through Laravel, then I expose APIs (tested with Insomnia and working correctly) that I call from my VueJS application.

So I made in my Vue project a component called LoginPage.vue and in which I call the API for login. To do this I have read documentation and examples online.

I have this problem, when I fill in the login form and click on the Login button on the browser opening the developer tools, in the console I have error 404.

Having no experience with vue I cannot understand what the problem may be.

I appreciate any advice or suggestions

  • LoginPage.vue
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>Compila il form sottostante con le tue credenziali per effettuare il login</p>
    <div>
      <form v-on:submit.prevent="loginForm">
        <div class="form-group">
          <input
            type="text"
            class="form-control"
            placeholder="Immetti la tua mail"
            id="mail"
            v-model="mail"
          >
        </div>
        <div class="form-group">
          <input
            type="password"
            class="form-control"
            placeholder="Immetti la tua password"
            id="psw"
            v-model="psw"
          >
        </div>
          <button class="btn btn-primary">Login</button>
      </form>
    </div>
    <p>oppure accedi con la tua identit&agrave; digitale SPID</p>
    <div> TODO - SPID BUTTON HERE</div>
  </div>
</template>

<script>

export default {
  name: "LoginPage",
  props: {
    msg: String,
  },
  data() {
    return {
      info: null
    };
  },
  created() {
    // Simple POST request with a JSON body using fetch
    const requestOptions = {
      method: "POST",
      headers: { "Content-Type": "application/json" }
    };
    fetch("http://localhost:8000/api/login", requestOptions)
      .then(response => response.json())
      .then(data => (this.info = data));
  }
};

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

EDIT:

I've modified my code like the code below, and now it works well, I place the code here that works correctly, hoping it will be of help to others as well

  • LoginPage.vue
<template>
  <div class="hello">
    <h1 style="font-size: 28px">{{ msg }}</h1>
    <p>
      Compila il form sottostante con le tue credenziali per effettuare il login
    </p>
    <div>
      <form class="login-form" @submit.prevent="doLogin">
        <div class="form-field">
          <input type="text" placeholder="email" v-model="user.email" />
        </div>
        <div class="form-field">
          <input
            type="password"
            placeholder="password"
            v-model="user.password"
          />
        </div>
        <div class="form-action">
          <button class="login-btn" type="submit">Submit</button>
        </div>
      </form>

      <span v-if="loading && !show">Loading...</span>
      <div v-else-if="show">
        <p>Login success: {{ successMessage }}</p>
        <p>Token: {{ token }}</p>
      </div>
    </div>
    <p>oppure accedi con la tua identit&agrave; digitale SPID</p>
    <div>TODO - SPID BUTTON HERE</div>
  </div>
</template>

<script>
export default {
  name: "LoginPage",
  props: {
    msg: String,
  },
  data() {
    return {
      user: {
        email: '',
        password: ''
      },
      show: false,
      loading: false,
      successMessage: '',
      token: ''
    }
  },
  methods: {
  async postData(url = '', data = {}) {
    const response = await fetch(url, {
      method: 'POST', // *GET, POST, PUT, DELETE, etc.
      headers: {
        'Content-Type': 'application/json'
      },
        body: JSON.stringify(data)
     });
     
     
     return response.json(); // parses JSON response into native JavaScript objects
    },
    doLogin() {
    this.loading = true
       this.postData('http://localhost:8000/api/login', this.user)
        .then(data => {
          this.token = data['data'].token;
          this.successMessage = 'Login avvenuto correttamente';
          this.loading = false;
          this.show = true;
        });
    
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

CodePudding user response:

First of all you have your api call in the created lifecycle hook and what you want is to bind the api call to the button clicked in your form. I also don't see any models in your data object. You are using the fetch api wrong, let me explain:

The steps:

  1. Setup the correct markup for a form
  2. Make the user object with the keys email and password and put that in your data object.
  3. When you use submit.prevent you will need to add a button in the form with the type submit
  4. Create a function in the methods object of Vuejs and add that to submit.prevent in your form

Here is an example with a test api:

const template = `
<div>
  <form  @submit.prevent="doLogin">
  <div >
    <input type="text" placeholder="Email" v-model="user.email" />
  </div>
  <div >
    <input type="password" placeholder="Wachtwoord" v-model="user.password" />
  </div>
  <div >
    <button  type="submit">Submit</button>
  </div>
</form>

<span v-if="loading && !show">Loading...</span>
<div v-else-if="show">
<p>Login success: {{ successMessage }}</p>
<p>Token: {{ token }} </p>
</div>
</div>
`;

const LoginForm = {
  name: 'LoginForm',
  data() {
    return {
      user: {
        email: '[email protected]',
        password: 'cityslicka'
      },
      show: false,
      loading: false,
      successMessage: '',
      token: ''
    }
  },
  template,
  methods: {
  async postData(url = '', data = {}) {
    const response = await fetch(url, {
      method: 'POST', // *GET, POST, PUT, DELETE, etc.
      headers: {
        'Content-Type': 'application/json'
      },
        body: JSON.stringify(data)
     });
     
     
     return response.json(); // parses JSON response into native JavaScript objects
    },
    doLogin() {
    this.loading = true
       this.postData('https://reqres.in/api/login', this.user)
        .then(data => {
          const { token } = data;
          this.token = token;
          this.successMessage = 'Yes sir!';
          this.loading = false;
          this.show = true;
        });
    
    }
  }
};

new Vue({
  el: '#root',
  components: { LoginForm },
  template: `<LoginForm />`
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="root"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related