I'm having a really hard time to figure out how to load a particular route when the activate event is fired. I'm creating an Electron application using the Electron-Vue framework and I've these following routes:
export default [
{
path: '/',
name: 'login-page',
component: require('components/LoginPageView')
},
{
path: '/tracker',
name: 'tracker-page',
component: require('components/TrackerPageView')
},
{
path: '*',
redirect: '/'
}
]
Now, I'd like to load the /tracker route once the app.on('activate') is fired on the following:
app.on('activate', () => {
if (mainWindow === null) {
createWindow()
}
})
The main reason behind this is I'm creating a two window Electron application. The first window would be the login and the second window would be user profiles. When the user already logged in and closed the app using the system close button, the app stays in the Dock bar and when the app is clicked, the Electron activate event is fired and the login screen shows again. Since the user is already logged in, I don't want the user to show the login window again. Any suggestion would be must appreciated.
I was finally able to achieve this by using the Vue-Router Per-Route Guard beforeEnter method. Here's my draft:
let auth = true
export default [
{
path: '/',
name: 'login-page',
component: require('components/LoginPageView'),
meta: {
auth: false
},
beforeEnter: (to, from, next) => {
if (auth) {
next('/tracker')
} else {
next()
}
}
},
{
path: '/tracker',
name: 'tracker-page',
component: require('components/TrackerPageView'),
meta: {
auth: true
}
},
{
path: '*',
redirect: '/'
}
]
Any feedbacks are most welcome to improve this even better :)
Related
Access /dashboard/profile get error
vue-router.esm.js:1958 Uncaught (in promise) Error: Redirected when going from “/home” to “/dashboard” via a navigation guard.
// router.ts
const routes: Array<RouteConfig> = [
{path: '/', redirect: {name: 'Home'}},
{path: '/home', name: 'Home', component: Home},
{
path: '/dashboard', component: () => import('../views/Dashboard.vue'),
meta: {isLogin: true},
children: [
{path: '', component: () => import('../views/Dash/Certificate/index.vue'), meta: {isViewer: true},
{path: 'profile', component: () => import('../views/Dash/ProfileComponent.vue')},
]
},
];
//guard
router.beforeEach((to, from, next) => {
const profilePath = "/dashboard/profile";
if (!to.matched.some(res => res.meta.isLogin)) {
return next();
}
// isNotLogin
if (!localStorage['currentUser'])
return next({path: "/", query: {redirect: to.fullPath}});
// isLogin
if (to.matched.some(res => res.meta?.isViewer)) {
viewService.isCertificateViewer ? next() : next({path: profilePath})
} else next()
});
I spent four hours trying to solve this same problem. This is the article I found that explained where the error was coming from: vue-router — Uncaught (in promise) Error: Redirected from "/login" to "/" via a navigation guard
Imagine you have routes a, b, and c. The user is on route a. They then click a link that is supposed to send them to route b. We then catch that in a route guard and redirect them to route c. This makes sense to the developer because there was a reason to redirect to route c, but the people in charge have decided that is a jarring experience to the user, and we shouldn't call route redirects in ways that don't make sense to the user.
tl;dr the problem is with how you initially direct to a route. Instead of router.push('/b') do router.push('/b').catch((e) => e); Just suppress the error and everything will work great.
I've read a number of solutions to this same problem, but none have worked for me. So here it goes.
I have a Vue 2 app using Express that runs on AWS Amplify. When I run my app locally in 'dev' mode (npm run serve) and 'start' mode (npm run build && node server.js), everything works fine.
The problem shows up when I deploy to Amplify. I can click nav buttons, go back, and go forward, all of which send me to the correct URL. However, the moment I refresh the page or manually enter a valid URL in the browser, the screen goes blank and the browser URL shows https://dontblowup.co/index.html.
Below is my server.js file:
const express = require('express')
const path = require('path')
const history = require('connect-history-api-fallback')
const app = express()
const port = process.env.PORT || 8080
const buildLocation = 'dist'
const staticFileMiddleware = express.static(path.resolve(__dirname, buildLocation))
app.use(staticFileMiddleware)
app.use(history())
app.use(staticFileMiddleware)
app.get('*', function (req, res) {
res.sendFile(path.resolve(__dirname, buildLocation, 'index.html'))
})
app.listen(port, () => {
console.log(`App listening to port ${port}...`)
console.log('Press Ctrl+C to quit.')
})
The solutions I found included using the history package in the server.js file and using the staticFileMiddleware before and after using history(). I also have 'history' mode set in the Vue app's router.js file (see below).
import Vue from "vue";
import VueRouter from "vue-router";
import Index from "./views/Index.vue";
import MainFooter from "./layout/MainFooter.vue";
import DashboardLayout from "#/layout/DashboardLayout.vue";
import Analytics from "#/views/Analytics.vue";
import TradeSheet from "#/views/TradeSheet.vue";
import KellyCriterionCalculator from "#/views/KellyCriterionCalculator.vue";
import PositionBuilder from "#/views/PositionBuilder.vue";
Vue.use(VueRouter);
export default new VueRouter({
mode: 'history',
routes: [
{
path: "/",
name: "Index",
components: { default: Index, footer: MainFooter },
props: {
footer: { backgroundColor: "black" }
},
meta: { requiresAuth: false }
},
{
path: "/dashboard",
redirect: "/dashboard/analytics",
name: "Dashboard",
component: DashboardLayout,
meta: { requiresAuth: true },
children: [
{
path: "/dashboard/analytics",
name: "Analytics",
component: Analytics
},
{
path: "/dashboard/trade-sheet",
name: "Trade Sheet",
component: TradeSheet
},
{
path: "/dashboard/risk-budget-calculator",
name: "Risk Budget Calculator",
component: KellyCriterionCalculator
},
{
path: "/dashboard/trade-analyzer",
name: "Trade Analyzer",
component: PositionBuilder
}
]
}
],
scrollBehavior: to => {
if (to.hash) {
return { selector: to.hash };
} else {
return { x: 0, y: 0 };
}
}
});
At this point I'm convinced there's something wrong with Amplify or Namecheap (where my DNS is configured). Unfortunately I haven't found anyone with the same issues using the same tech, so hopefully someone here can help.
Cheers!
You need to set up it on the Amplify Console
Navigate to the Amplify Console
On the left menu click on "Rewrites and redirects"
Click on Edit
Add the rule:
Source: </^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>
Target: /
Type: 200
You can read more about it here
Go to section: Redirects for Single Page Web Apps (SPA)
Most SPA frameworks support HTML5 history.pushState() to change browser location without triggering a server request. This works for users who begin their journey from the root (or /index.html), but fails for users who navigate directly to any other page. Using regular expressions, the following example sets up a 200 rewrite for all files to index.html except for the specific file extensions specified in the regular expression.
the better way to handle SPA call to index.html will be
app.get(/.*/, (req, res) => res.sendFile(__dirname + '/dist/index.html'))
in frontend vue router you need to add a redirect route like this
{
path: "*",
redirect: "/"
}
Good day.
When running my app i get the following error related to my vue-router:
TypeError: e is not a function
however i have nothing ... i simply named "e" in my code.
I have a few before each options but nothing too big besides a few cookies deletions.
I have a few imports of apps and i am trying to use them in my router and they all work. So does the cookies. I did the beforeEach() method a few times to see if the error was there but so far no luck.
i got no idea of what is going on.
EDIT: When trying to figure this i was comenting on my code to see if i could find the error and when i removed most of the beforeEach() section i left on the next() function and a new error showed sayin "t is not a function", so i guess for some reason java script is only recognizing the last letters of my funcions, like t in next() and e in some().
EDIT2: After removing unecessary code that i copied from another project apperently the error happens in my next() function.
here's my router code:
import Vue from "vue";
import Router from "vue-router";
import Dashboard from "#/views/Dashboard.vue";
import Opcoes from "#/views/settings.vue";
import LoginForm from "#/components/component/loginForm.vue";
import store from "./store.js";
import Cookies from "js-cookie";
Vue.use(Router);
let router = new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/",
name: "loginForm",
component: LoginForm,
meta: {
guest: true
}
},
{
path: "/dashboard",
name: "Dashboard",
component: Dashboard,
meta: {
requiresAuth: true
}
},
{
path: "/opcoes",
name: "Opcoes",
component: Opcoes,
meta: {
requiresAuth: true
}
},
{
path: "/sair",
name: "Sair",
component: LoginForm,
meta: {
requiresAuth: true
}
}
]
});
router.beforeEach((to, from, next) => {
const expirationDate = Cookies.get("expireIn");
const now = new Date().getTime();
if (now >= expirationDate) {
Cookies.remove("expirationDate");
Cookies.remove("token");
Cookies.remove("userId");
store.dispatch('LOGOUT');
} else {
next();
}
});
export default router;
Heres a print of my stack trace:
My Big Fat Guess
The error message points to line 2203 (line 1921 is part of a generic error handler). This line is in the Router push() method
onComplete && onComplete(route);
My guess is, somewhere in your code not shown in your question (perhaps in your LoginForm component), you are calling this.$router.push() with a second argument that is not a function, eg
this.$router.push({ name: 'Dashboard' }, somethingNotAFunction)
Other problems (from previous versions of the question)
Your / route (loginForm) has no params so this...
next({
path: "/",
params: { nextUrl: to.fullPath }
});
is invalid. Did you perhaps mean to send nextUrl as a query parameter. If so, use
next({ name: 'loginForm', query: { nextUrl: to.fullPath } })
You also have
next({ path: "login" });
and
next({ name: "login" });
neither of which exist in your routes. You should only forward the route request to existing routes.
Finally, if you're using Vuex, you should not be directly assigning state values. In strict-mode, this
store.state.isLoggedIn = false
will trigger an error. You should be committing state mutations instead.
I have the following structure in vue.js ,using vue-router.
routes: [
{
path: '/domains',
component: ListOfDomains
},
{
path: '/domain/:domainName',
component: Domain,
children: [{
// Photos Tab content will be rendered inside domain's <router-view>
// when /domain/:id/photos is matched
path: 'posts',
name: 'posts',
component: PostsTabContent
},
{
path: 'photos',
name: 'photos',
component:PhotosTabContent
}
]
}
]
In my Domain component I use a watcher to fetch domain related data from server such as:
"$route": function(to, from) {
console.log("watcher triggered");
//do update only if domain has changed
//do something , ajax request , update store etc
}
This seems to work fine, but my problem is that I only want to do my updates if the url changes from, say, domain/domain23/posts to domain/domain45/posts and not when it changes from domain/domain23/posts to domain/domain23/photos.
How can I watch only that level in the route for changes?
I am building an app with the following route settings.
export default new Router({
routes: [
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/home',
name: 'Dashboard',
component: Dashboard,
beforeEnter(to, from, next) {
if (!store.getters.isLoggedIn) {
next('/login');
} else {
next();
}
}
},
{
path: '/',
redirect: '/home'
}
]
});
I also set query parameters based on some select boxes I have by using $router.push say as follows.
this.$router.replace({
query: {
scope: this.$store.getters.filterScope
}
});
Problems I have
Reloading the page removes the query params from the URL.
Updating one query parameter removes the other one I had. Example - updating scope using the above method removes the dateRange parameter I already had.
I am using Vuex too so is there any way I can manage these query params using the store?
If you store your parameters in vuex and you don't use vuex-persistedstate, when you refresh the page state will be removed.
So, my suggestion for you:
your-awesome-site.com/dashboard?first=hello&second=hi
In your Dashboard component, you can do like this
mounted () {
console.log(this.$route.params)
// Update vuex state filterScope
}
So you will retrieve your parameters from url and save it in vuex.
Also you can solve your second issue using this.$route.params