• 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

Object Storage Arubacloud
0 głosów
120 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ź 135 wizyt
pytanie zadane 10 lutego 2020 w JavaScript przez Greeenone Pasjonat (16,100 p.)
0 głosów
1 odpowiedź 1,230 wizyt
pytanie zadane 27 grudnia 2018 w JavaScript przez Arcix Nowicjusz (180 p.)
0 głosów
0 odpowiedzi 487 wizyt

92,550 zapytań

141,394 odpowiedzi

319,522 komentarzy

61,935 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...