• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Użycie this w action / mutation - VueJS

VPS Starter Arubacloud
0 głosów
119 wizyt
pytanie zadane 11 lipca 2020 w JavaScript przez Greeenone Pasjonat (16,100 p.)

Hej,

Mam pewien problem ponieważ nie wiem jak się odwołać do routingu. Mam kod który wylogowuje użytkownika ale niestety nie wiem jak dodać także zmianę routing z aktualnego na login

const actions = {
  [VERIFY_AUTH](context) {
    if (JwtService.getToken()) {
      ApiService.setHeader();
      ApiService.get("/sanctum/verify")
        .then(({ data }) => {
          context.commit(SET_AUTH, data);
        })
        .catch(() => {
          context.commit(PURGE_AUTH);
        });
    } else {
      context.commit(PURGE_AUTH);
    }
  },
};

const mutations = {
  [PURGE_AUTH](state) {
    state.isAuthenticated = false;
    state.user = {};
    state.errors = {};
    this.$router.push({ name: "login" });
    JwtService.destroyToken();
  }
};

Nie wiem w którym miejscu dodać

this.$router.push({ name: "login" });

Próbowałem dodać w catch pod context.commit purge ale mam następujący błąd:

Uncaught (in promise) TypeError: this.$router is undefined

Próbowałem dodać .bind(this) ale nie pomogło.

komentarz 11 lipca 2020 przez ScriptyChris Mędrzec (190,190 p.)
edycja 11 lipca 2020 przez ScriptyChris

Jak i gdzie wołasz funkcje przekazujesz obiekty actions i mutations? Czym jest tam w ich metodach this?

komentarz 11 lipca 2020 przez Greeenone Pasjonat (16,100 p.)

Więc tak:

Przy ładowaniu strony jest następujący kod który ma na celu sprawdzić czy użytkownik jest zalogowany poprzez wysłanie tokenu

Main.js

  // Ensure we checked auth before each page load.
  Promise.all([store.dispatch(VERIFY_AUTH)]).then(next);

Ten kod odnosi się to tego:

Auth.module.js

  [VERIFY_AUTH](context) {
    if (JwtService.getToken()) {
      ApiService.setHeader();
      ApiService.get("/sanctum/verify")
        .then(({ data }) => {
          context.commit(SET_AUTH, data);
        })
        .catch(() => {
          context.commit(PURGE_AUTH);
        });
    } else {
      context.commit(PURGE_AUTH);
    }
  },

Jeśli token nie jest prawidłowy, to wylogowuje za pomocą tego kodu:

  [PURGE_AUTH](state) {
    state.isAuthenticated = false;
    state.user = {};
    state.errors = {};
    JwtService.destroyToken();
  }

Poza wylogowaniem (W sensie wyczyszczeniem obiektów i usunięciu tokena) chciałbym także przekierować użytkownika na stronę logowania za pomocą:

this.$router.push({ name: "login" })

 

komentarz 11 lipca 2020 przez ScriptyChris Mędrzec (190,190 p.)

A jakie są odpowiedzi na pytania z poprzedniego komentarza? :) W powyższym kodzie nie widzę użyć actions ani mutations.

komentarz 11 lipca 2020 przez Greeenone Pasjonat (16,100 p.)

Wybacz, już piszę (O ile dobrze zrozumiałem, że tak to działa).

Ten kod z pliku main.js odnosi się do action z pliku auth.module.js

  // Ensure we checked auth before each page load.
  Promise.all([store.dispatch(VERIFY_AUTH)]).then(next);

A tutaj jest cała zawartość pliku auth.module.js

import ApiService from "@/core/services/api.service";
import JwtService from "@/core/services/jwt.service";

// action types
export const VERIFY_AUTH = "verifyAuth";
export const LOGIN = "login";
export const LOGOUT = "logout";
export const REGISTER = "register";
export const UPDATE_USER = "updateUser";

// mutation types
export const PURGE_AUTH = "logOut";
export const SET_AUTH = "setUser";
export const SET_ERROR = "setError";

const state = {
  errors: null,
  user: {},
  isAuthenticated: !!JwtService.getToken()
};

const getters = {
  currentUser(state) {
    return state.user;
  },
  isAuthenticated(state) {
    return state.isAuthenticated;
  }
};

const actions = {
  [LOGIN](context, credentials) {
    return new Promise(resolve => {
      ApiService.post("/sanctum/token", credentials)
        .then(({ data }) => {
          context.commit(SET_AUTH, data);
          resolve(data);
        })
        .catch(({ response }) => {
          context.commit(SET_ERROR, response.data.errors);
        });
    });
  },
  [LOGOUT](context) {
    context.commit(PURGE_AUTH);
  },
  [REGISTER](context, credentials) {
    return new Promise((resolve, reject) => {
      ApiService.post("users", { user: credentials })
        .then(({ data }) => {
          context.commit(SET_AUTH, data);
          resolve(data);
        })
        .catch(({ response }) => {
          context.commit(SET_ERROR, response.data.errors);
          reject(response);
        });
    });
  },
  [VERIFY_AUTH](context) {
    if (JwtService.getToken()) {
      ApiService.setHeader();
      ApiService.get("/sanctum/verify")
        .then(({ data }) => {
          context.commit(SET_AUTH, data);
        })
        .catch(() => {
          context.commit(PURGE_AUTH);
        });
    } else {
      context.commit(PURGE_AUTH);
    }
  },
  [UPDATE_USER](context, payload) {
    const { email, username, password, image, bio } = payload;
    const user = { email, username, bio, image };
    if (password) {
      user.password = password;
    }

    return ApiService.put("user", user).then(({ data }) => {
      context.commit(SET_AUTH, data);
      return data;
    });
  }
};

const mutations = {
  [SET_ERROR](state, error) {
    state.errors = error;
  },
  [SET_AUTH](state, data) {
    state.isAuthenticated = true;
    state.user = data.user;
    state.errors = {};
    if(data.token){
      JwtService.saveToken(data.token);
    }
    console.log('TOKEN');
    console.log(JwtService.getToken());
  },
  [PURGE_AUTH](state) {
    state.isAuthenticated = false;
    state.user = {};
    state.errors = {};
    JwtService.destroyToken();
    
  }
};

export default {
  state,
  actions,
  mutations,
  getters
};

this ma się odnosić do routingu, a dokładnie zmienić aktualni link na /login. Chciałbym go używać w action VERIFY_AUTH (w catch) w momencie, kiedy token wygaśnie, jest niezgodny

komentarz 11 lipca 2020 przez ScriptyChris Mędrzec (190,190 p.)

W pytaniu obiekt mutations zawierał metodę [PURGE_AUTH](state), która miała wywołanie this.$router, a w powyższym kodzie tego wywołania nie ma.

W każdym razie, mutations jest exportowane dokąd? Chciałem zobaczyć jak to jest używane, bo coś musi na nim wołać metodę [PURGE_AUTH](state) i od tego zależy czym jest this wewnątrz niej. Poza tym, prosiłem też żebyś pokazał, czym jest this w środku tej metody (przed wywołaniem this.$router.push({ name: "login" });

komentarz 11 lipca 2020 przez Greeenone Pasjonat (16,100 p.)

Więc tak:

Przeniesienie na /login dodaję w Verify

  [VERIFY_AUTH](context) {
    if (JwtService.getToken()) {
      ApiService.setHeader();
      ApiService.get("/sanctum/verify")
        .then(({ data }) => {
          context.commit(SET_AUTH, data);
        })
        .catch(() => {
          context.commit(PURGE_AUTH);
          //Przeniesienie użytkownika na strone logowania
          this.$router.push({ name: "login" })
        });
    } else {
      context.commit(PURGE_AUTH);
    }
  },

I ten dodatek wywołuje następujący błąd:

Uncaught (in promise) TypeError: _this.$router is undefined

VERIFY_AUTH jest użyte tylko w main.js (Żaden inny plik nie zawierał w sobie tego wyrażenia po za main.js oraz store/auth.module.js

PURGE_AUTH natomiast znajduje się tylko w pliku store/auth.module.js

komentarz 11 lipca 2020 przez ScriptyChris Mędrzec (190,190 p.)

this w catchu jest pewnie undefined (zakładając, że to moduły), więc żeby this było komponentem (lub tym, co ma metodę $router) możesz albo zbindować callback do catch (w takim przypadku zamień arrow function, na "zwykłą" funkcję), albo przechowaj this w zmiennej o nazwie np. self (ją stwórz w miejscu, w którym this jest tym, co ma property $router), albo stwórz ten callback strzałkowy do catcha w miejscu, w którym this jest tym czym ma być - wtedy arrow function będzie trzymać odziedziczony this w momencie wywołania go w catch.


Ciekawe, że w błędzie jest mowa o _this.$router, a więc _this, a nie this.

komentarz 11 lipca 2020 przez Greeenone Pasjonat (16,100 p.)
Dzięki wielkie za pomoc. Udało mi się rozwiązać ale innym sposobem i nawet nie wiem czy prawidłowym. Zamienienie funkcji strzałkowej na zwykła nie pomogło a co do drugiej opcji to za bardzo nie rozumiem jak ogarnąć, wychodzi to po za zakres moich umiejętności.

Problem rozwiązałem tak, że dałem watch na zmienną isAuthenticated. Jeśli zwraca false, user jest przekierowany na login
komentarz 11 lipca 2020 przez ScriptyChris Mędrzec (190,190 p.)

Zamienienie funkcji strzałkowej na zwykła nie pomogło

A zbindowałeś tą "zwykłą" funkcję?

komentarz 12 lipca 2020 przez Greeenone Pasjonat (16,100 p.)

Tak, i nadal mam

Uncaught (in promise) TypeError: this.$router is undefined

Ja się poddałem. Tyle czasu przy tym spędziłem, że zostanę raczej przy watchu

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 134 wizyt
pytanie zadane 10 lutego 2020 w JavaScript przez Greeenone Pasjonat (16,100 p.)
0 głosów
1 odpowiedź 1,215 wizyt
pytanie zadane 27 grudnia 2018 w JavaScript przez Arcix Nowicjusz (180 p.)
0 głosów
0 odpowiedzi 474 wizyt

92,454 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...