How do you know if you can't go back VueJS - vue.js

I would like to write a method that links to the homepage if I can't go back.
a code a bit like that:
if (**router.back.length == 0**){
router.push({name:"Home"})
}else {
router.back();
}
}
the problem is i dont know how to tell if the .back () is possible or not.
I am currently on a pageNotFound, I go to the current page using the following redirect
path: "/:catchAll(.*)",
name: "PageNotFound",
component: () =>
import(/* webpackChunkName: "NotFound" */ "#/views/PageNotFound.vue")
}
Thanks for your help!

Had similar case once. Try something like this (treat it like a pseudo code):
data: () => ({
fromRoute: null
}),
beforeRouteEnter (to, from, next) {
next(vm => {
vm.fromRoute = from;
})
},
methods: () {
handleBack() {
if (!this.fromRoute.name) {
router.push({name:"Home"});
} else {
router.back();
}
}
}
More info here: https://forum.vuejs.org/t/how-to-go-back-or-go-home/30242/3

Use this code to achieve the desired result. Make sure you are using [Named Routes][1].
export default {
data() {
return {
fromRoute: null
};
},
beforeRouteEnter(to, from, next) {
next((vm) => {
vm.fromRoute = from;
});
},
methods: {
goBack() {
if (!this.fromRoute.name) {
this.$router.push("/");
} else {
this.$router.back();
}
},
},
};
[1]: https://router.vuejs.org/guide/essentials/named-routes.html

By looking in the VueJs doc I found the solution
goBack() {
if(this.$router.getRoutes().length==0){
this.$router.push({name:"Home"})
}else{
this.$router.back();
}
}
https://router.vuejs.org/api/#router-onready

Related

Nuxt js Router Push Not Working After Delete

I've created a simple CRUD with Nuxt. Data is provided by Lumen. I got a problem with the DELETE, data is deleted but Nuxt does not redirect to the other page.
Here is my script:
<script>
export default {
name: 'EmployeePage',
data() {
return {
fields: ['name','email','image','address'],
emplyees:[],
}
},
mounted() {
this.$axios.get('/employee').then(response => {
this.pegawais = response.data.data
}).catch(error => {
console.log(error.response.data)
})
},
methods: {
async delete(id) {
await this.$axios.delete(`/employee/${id}`).then(response => {
this.$router.push({ name: 'employee' }) <-----this redirect not working
})
}
}
}
</script>
I want Nuxt to redirect to the employee page that display all the data after the deletion.
You should not mix async/await and .then. Use the first approach, that way you will not have the .then callback hell and it will be cleaner overall.
Like this
<script>
export default {
name: 'EmployeePage',
data() {
return {
fields: ['name', 'email', 'image', 'address'],
emplyees: [],
}
},
async mounted() {
try {
const response = await this.$axios.get('/employee')
this.pegawais = response.data.data
} catch (error) {
console.log(error.response.data)
}
},
methods: {
async delete(id) {
await this.$axios.delete(`/employee/${id}`)
await this.$router.push({ name: 'employee' })
},
},
}
</script>
await this.$router.push does not require an await but it's a Promise too, so I'm writing it like that in case you need to call something else afterwards.
this.$axios.$get('/employee') can also be used if you want to remove a .data aka this.pegawais = response.data as shown here.

How can I make the vue-router change when changing parameters? (vuex)

I'm making an app that has advanced search api.
You can choose what to look for and how to sort the results. The problem is that the page (vue-router) is updated only when the request changes, but it also should be updated when you change the search terms
How i can do this? I don't even have any ideas.
There is my code that is responsible for requesting the API and updating the router when the request is updated
export default {
name: "Search",
data: function () {
return {
selectedTag: 'story',
selectedBy: '',
};
},
components: {
'Item': Item
},
mounted() {
this.items = this.getItems(this.id)
},
beforeRouteUpdate(to, from, next) {
this.items = this.getItems(to.params.id);
next();
},
methods: {
getItems(id) {
this.items = this.$store.dispatch('FETCH_SEARCH_RESULTS', {id, tag: this.selectedTag, by: this.selectedBy});
return this.items;
},
},
created: function () {
this.getItems(this.$route.params.id);
},
computed: {
items: {
get() {
return this.$store.state.searchResults;
},
set(value) {
this.$store.commit("APPEND_SEARCH_RESULTS", value);
}
}
}
}

Making pagination with laravel paginate() and vuex,

I am really having a hard time to solve this problem. Trying to make pagination by using vuex. But I can't update actions when I change the argument value.
For example to go to the next page, I tried a simple way
in component: home
<button #click="nextPage()">{{currentPage}}</button>
I send the argument to actions.
mounted(){
this.$store.dispatch('bridalApi', {currentPage})
},
data(){
return {
currentPage: 1,
};
},
methods: {
nextPage(){
this.currentPage++
}
},
in store.js
I take the argument that I commited.
actions: {
bridalApi({commit}, currentPage){
axios.get("api/bridal?page=" + currentPage)
.then(response => {
commit("setBridals", response.data);
})
.catch(e => {
console.log(e);
})
},
}
it's clearly I can't update the argument inside actions. Because when I click the button, it doesn't go to next page. I mean currentPage inside actions doesn't updated. This was the first way. So, I tried different approach to solve this problem which is like below.
in component: home
<button #click="nextPage()">{{pager}}</button>
I set/get the currentPage, and change the state.
methods: {
nextPage(){
this.pager++
}
},
computed: {
...mapGetters([
"getBridals",
]),
pager: {
set(val){
this.$store.commit("setPagination", val);
},
get(){
return this.$store.state.bridal.pagination.currentPage;
}
},
bridals() {
return this.getBridals;
},
},
in Store.js
state: {
bridals: [],
pagination: {
currentPage: 1,
},
},
mutations: {
setBridals(state, bridal){
state.bridals = bridal;
},
setPagination(state, pager){
state.pagination.currentPage = pager;
},
},
getters: {
getBridals(state){
return state.bridals
},
},
actions: {
bridalApi({commit,state}){
console.log(state.pagination.currentPage)
axios.get("api/bridal?page=" + state.pagination.currentPage)
.then(response => {
commit("setBridals", response.data);
})
.catch(e => {
console.log(e);
})
},
}
But this way is not working either. And I am very much out of ideas. How can I update the actions? What is the right way to use vuex for pagination?...
I am not sure is it's the right way to this. But solved it. Used the first way I mentioned in the question and update home component like below.
data(){
return {
currentPage: 1,
};
},
watch: {
currentPage() {
this.$store.dispatch("bridalApi", this.currentPage);
console.log("ok")
}
},
You can use a mutation for this like
state:{
data:[]
}
mutations:{
SET_DATA:(state , data) => {
return state.data = data
}
}
actions: {
dataApi({commit}, currentPage){
console.log(currentPage)
axios.get("http://website.com/api/endpoint?page="+currentPage)
.then(response => {
commit('SET_DATA' , response.data)
})
.catch(e => {
console.log(e);
})
}
}
I would recommend using LaravelVuePagination package for this.
That way you can have something like:
<pagination :data="bridals" #pagination-change-page="getBridals"></pagination>
export default {
name: 'BridlaList',
mounted() {
this.getBridals();
},
methods: {
getBridals(page = 1){
this.$store.dispatch('getBridals',{
page: page
});
},
}

Routing guards in Framework 7 Vue

When I do the following:
{
path: '/chat/',
async(routeTo, routeFrom, resolve, reject) {
if (localStorage.getItem('token')) {
resolve({
component: require('./assets/vue/pages/chat.vue'),
});
} else {
resolve({
component: LoginPage
});
}
},
}
Everything works as expected, but if I do this:
{
path: '/chat/',
component: require('./assets/vue/pages/chat.vue'),
async(routeTo, routeFrom, resolve, reject) {
if (localStorage.getItem('token')) {
resolve();
} else {
resolve({
component: LoginPage
});
}
},
}
Then the component always resolves, regardless of the async. This is also the case when I try to use a beforeEnter function instead of async; if the component is defined at the top level of the route, it always resolves.
How could I put an authentication middleware on a route?
Maybe try this.
const checkAuth = (to, from, resolve, reject) => {
if (localStorage.getItem('token')) {
resolve({ component: routeComponentMap[to.name] })
} else {
resolve({ component: LoginPage })
}
}
const routeComponentMap = {
CHAT: require('./assets/vue/pages/chat.vue')
}
const routes = [{
path: "/chat/",
name: "CHAT",
async: checkAuth
}]

Vue-router beforeRouteEnter Vue-Resource request

I have used this link as a reference to make a request before entering a route:
https://router.vuejs.org/en/advanced/data-fetching.html
import Vue from 'vue'
import VueResource from 'vue-resource'
Vue.use(VueResource)
function getCities () {
return Vue.http({
method: 'GET',
url: process.env.base_url + 'cities'
})
}
export default {
data () {
return {
cities: []
}
},
beforeRouteEnter (to, from, next) {
getCities((err, cities) => {
if (err) {
next(false)
} else {
next(vm => {
vm.cities = cities.data
})
}
})
},
watch: {
$route () {
this.cities = []
getCities((err, cities) => {
if (err) {
this.error = err.toString()
} else {
this.cities = cities.data
}
})
}
}
However it doesn't seem to be working for me. I have tested this code and the request is successfully being made. However the result is not being returned. Currently, the request itself is being returned from the function, but I cannot show it in the beforeRouteEnter callback where it supposedly should assign it to vm.cities neither in the watch $route section.
Any help/opinion is appreciated.
The Vue.http method returns a promise, so the code should read:
beforeRouteEnter (to, from, next) {
getCities().then(response => {
next(vm => vm.cities = response.body)
}
}