1

I have a problem , I'm new using vue js and I'm developing a web app with vue 3 using vuex. I have this component called protected

<template>
  <div>
    <div>
      <section class="text-gray-600 body-font bg-gray-100">
        <div
          class="
            container
            xl:px-32
            px-5
            py-36
            mx-auto
            flex flex-wrap
            items-center
          "
        >
          <div class="lg:w-3/5 md:w-1/2 md:pr-16 lg:pr-0 pr-0">
            <h1
              class="
                title-font
                font-bold
                lg:text-7xl
                text-6xl text-white text-center
                md:text-left
              "
            >
              Materiality Reporting Tool (MRT)
            </h1>
            <p
              class="
                leading-relaxed
                mt-4
                lg:text-3xl
                text-2xl
                lg:max-w-xl
                font-medium
                text-white text-center
                md:text-left
              "
            >
              Tool for getting surveys data and plot it into a graph.
            </p>
          </div>
          <div
            class="
              lg:w-2/6
              md:w-1/2
              bg-white
              shadow-lg
              rounded-lg
              p-8
              flex flex-col
              md:ml-auto
              w-full
              mt-10
              md:mt-0
            "
          >
            <div class="relative mb-4">
              <input
                type="password"
                name="password"
                placeholder="Password"
                v-model="pass"
                class="
                  w-full
                  bg-white
                  rounded
                  border border-gray-300
                  outline-none
                  text-lg text-gray-700
                  py-1
                  px-3
                  leading-8
                  transition-colors
                  duration-200
                  ease-in-out
                "
              />
            </div>

            <div
              id="alertlogin"
              class="
                bg-red-100
                border border-red-400
                text-red-700
                px-4
                py-3
                rounded
                relative
                mb-3
              "
              role="alert"
              style="display: none"
            >
              <span class="block sm:inline">{{ this.alert }}</span>
            </div>

            <button
              @click="getpassword"
              class="
                text-black
                font-pluton
                border-0
                py-2
                px-8
                font-medium
                rounded
                text-xl
                bg-yellow
              "
            >
              ENTER
            </button>
          </div>
          <div
            class="
              lg:w-2/6
              md:w-1/2
              bg-transparent
              rounded-lg
              p-8
              flex flex-col
              md:ml-auto
              w-full
              mt-3
              md:mt-0
            "
          ></div>
        </div>
      </section>
    </div>
  </div>
</template>

<script>
import axios from "axios";
import router from '../router'
import { mapState } from "vuex";
import { mapMutations } from "vuex";
export default {
  name: "Protected",

  data() {
    return {
      pass: null,
      alert: null,
    };
  },


  methods: {

    getpassword() {
      if (this.pass == null) {
        $("#alertlogin").show();
        this.alert = "Please enter your password.";

      } else {
        let configforms = {
          method: "get",
          url: `http://localhost/typeform_surveys_new/api.php?request=login&pass=${this.pass}`,
        };

        axios(configforms)
          .then(function (response) {
            console.log(response.data)
            if (response.data === 1) {
              sessionStorage.setItem('authvox',1)
              router.push("/home");
            } else {
              $("#alertlogin").show();
              this.alert = "Password Incorrect.";
            }
          })
          .catch(function (error) {
            console.log(error);
          });
      }
    },
  },
};
</script>

in my data object I have the alert set with value null, then i print the alert value into the html using this.alert... I have a method calleed getpassword which validates if the input is empty or if the value the user enter on that input is incorrect. If it is empty the alert shows a message "Please enter a password", if the value the user typed is wrong the alert shows a message "Password incorrect"... I change the value of the alert doing: this.alert = "Password incorrect" or this.alert = "Please enter your password."; ... My code works when the user leaves the input empty, the program shows the message saying "Please enter a password" but when the input is not empty and the user typed an incorrect password, I get this error: TypeError: Cannot set properties of undefined (setting 'alert')

I tried using computed but still the same error. The funny thing is that if I put the this.alert = "Password Incorrect." outside the axios method it works.

1 Answer 1

1

Firstly I would exclude the use of jQuery and use the native v-show or v-if to show/hide a section.

Why the value won't update I think is because this.alert inside the Axios function refers to axios. What I do most of the time is define it in the code as a different constant.

function getpassword(){
  const self = this
  axios(configforms)
      .then(function (response) {
        console.log(response.data)
        if (response.data === 1) {
          sessionStorage.setItem('authvox',1)
          router.push("/home");
        } else {
          $("#alertlogin").show();
          self.alert = "Password Incorrect.";
        }
      })
  
}
Also you shouldn't use sessionStorage but should use vuex. It's a way better state management and really easy and in combination with vuex-persistedstorage you would use localStorage

I would add below the v-show in favor of jQuery

<div
  id="alertlogin"
  v-show="alert"
  class="
    bg-red-100
    border border-red-400
    text-red-700
    px-4
    py-3
    rounded
    relative
    mb-3
  "
  role="alert"
  style="display: none"
>
Also I don't think you have to import router manually. If you registered into your main.js file then you can just reference it as this.$router.push()

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much!!!
If you usse arrow functions then 'this' keeps its context so you can avoid using 'self'. gist.github.com/pastranastevenaz/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.