I was wondering if I can do the following with a ternary operator instead of if-else.
if (myPath === '/') {
next({ path: '/articles', query: { page: 1 } });
} else {
next();
}
What I want to do is to replace all of that with just one line:-
next(myPath === '/' ? { path: '/articles', query: { page: 1 } } : nothing);
If I'm going in the right direction then it just mainly boils down to passing 'nothing' to the next function. This is a code sample from the VueJS router navigation guard by the way if it's any help.
Is something like this possible?
Related
This is my code within in router.js file
{
name: "Admin",
path: "/admin/",
component: () => import("#/views/admin/Index"),
children: [
// Dashboard
{
name: "Dashboard",
path: "dash",
component: () => import("#/views/admin/Dash"),
},
{
name: "Campaign Management",
path: "campaign",
component: () =>
import("#/views/CampaignManagementNew/CampaignManagment"),
},
]
}
I set a variable 'status' in the localStorage.
I want to route only, if 'status' is true (localStorage item).
Otherwise, I not need to routing to child components.
How I use if conditions to routing?
You want to implement a pretty common pattern for 'protecting' routes behind a flag. In order to accomplish this, you should add a meta property to the routes you want to 'protect' behind a secondary check (the localStore value). Then you will need to create a router guard that checks the meta flag and routes the user based on those conditions.
You can see an example of it here: https://router.vuejs.org/guide/advanced/meta.html#route-meta-fields
In your case you would want to replace the auth.loggedIn() with your function that can check the localStorage value. So something like this:
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresLocalStorageValue)) {
if (!checkLocalStorageValue()) {
next({ path: '/not-authorized-page-missing-local-store'})
} else {
next()
}
} else {
next() // make sure to always call next()!
}
})
I need to match a route like this: /route*
I mean, one that matches /route1, /route2, /route999, /routewhatever
I don't want to match /route/whatever. I want that if the user puts anything after the main name it's ignored.
/route* didn't work. Is this possible ?
the only way I see is to use a UrlMatcher
export function wildCardMatcher(url: UrlSegment[]) {
return url.length === 1 && url[0].path.startsWith('route') ? ({consumed: url}) : null;
}
and then
{ matcher: wildCardMatcher, component: HomeViewComponent,}
here's a demo
UrlMatcher in Angular lets you define your own function to match a url to a route.
You could do something like
function wildCardMatcher(url: UrlSegment[]) {
return url[0].path.slice(0,5) === 'route' ? ({consumed: url}) : null;
}
routes = [{
matcher: wildCardMatcher,
component: Whatever
}]
https://angular.io/api/router/UrlMatcher
In my Vue.js project, I want to display my 404 page, if a route parameter is invalid. For now, I'm using the following code for that:
this.$router.replace({ path: '/404' });
Is there a way to do that without modifying the URL? I want the user to still be able to copy the browser's original URL line. Is there some kind of a silent: true parameter?
With vue-router, the URL is the source of truth. If the URL changes, so does the rendering. You can't "pause" the router. (This is a flaw in vue-router that has been bugging me for ages, but I digress.)
You just have to display the 404 page without modifying the route. Have some display404 data property in your root component that you can set to display the 404 page manually in the template instead of the <router-view>, e.g:
<div>
<my-404-page v-if="display404"/>
<router-view v-else/>
</div>
To display the 404 page from any component:
this.$root.display404 = true
Of course this is just a basic example to demonstrate what I mean, you might want to use Vuex to share the state, or use an event bus, or you can display the 404 page in some other way that works for you, etc.
This was fixed in Vue Router 4 which you can see on the second example in the docs.
Build your NotFound route like this:
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: NotFound
},
Then you can use a beforeEnter navigation guard on your dynamic Vue like so:
// In your router/index.js file...
{
path: 'users/:id',
name: 'User Detail',
component: UserDetail,
beforeEnter(to, from) {
// See if that query exists in your data...
const exists = data.users.find(
user => user.id === parseInt(to.params.id)
)
if (!exists) {
// THE IMPORTANT PART
// Return your not found view...
return {
name: 'NotFound',
// Match the path of your current page and keep the same url...
params: { pathMatch: to.path.split('/').slice(1) },
// ...and the same query and hash.
query: to.query,
hash: to.hash,
}
}
}
}
Haven't tested this in a Component yet, but I'd assume it'd be the same logic in the beforeRouteEnter navigation guard.
Not 100% sure what you are asking, but is either of these any help?
A catch all route:
From Vue.js docs "Catch all route"
Or if you are managing a response form a call (method/fetch/ etc): Use a combination of try/catch and a "loading" data value to change the display or what component is loaded.
Based on Decade Moon's solution, I did the following:
main.js
import Error404 from './views/error/404.vue'
Vue.component('error-404', Error404)
404.vue
<template>
<div>
<h1>Page not found</h1>
<p>Whatever...</p>
</div>
</template>
<script>
export default {
name: 'Page not found'
}
</script>
router --> index.js
const PageNotFound = () => import('#/views/error/404')
function configRoutes() {
return [
{
path: '/',
name: 'Home',
component: TheContainer,
children: [
// ...
{
path: '404',
name: 'Page not found',
component: PageNotFound,
alias: '*'
}
]
}
]
}
My Page which should display the 404 error
<template>
<div class="animated fadeIn" v-if="clientSettings">
...
</div>
<error-404 v-else></error-404>
</template>
<script>
export default {
name: 'Test',
data() {
return {
clientSettings: null
};
},
async created() {
this.setClientConfig();
},
watch: {
'$route.params.id': function (id) { this.setClientConfig(id);}
},
methods: {
setClientConfig(id) {
if (!id) {
id = this.$route.params.id;
// Redirect to the first valid list, if no parameter is proviced
if (!id) {
this.$router.push({ name: 'Test', params: { id: this.$root.clientConfiguration[0].name } });
return;
}
}
// Set client settings
this.clientSettings = this.$root.clientConfiguration.find(cc => cc.name === id);
// This will return null, if no entry was found, therefore the template will jump into the v-else
}
}
}
</script>
in this firebase -VueJS app i'm building also i'm trying to set basic security rules to surf on it , utilizing router guards.
In my main.js i put this code refering to allow permission or not attuning with the user auth situation, but throws me this 'vue-router.esm.js?xxx RangeError: Maximum call stack size exceeded':
router.beforeEach( (to, from, next) => {
if(store.getters.getUser == null || store.getters.getUser == undefined ){
next('/welcome',)
}
else return next()
}
);
also as alternative i did try to use a beforeEnter hook on my router.js file on each and every path but despite of being working , any time i reload the page for any reason throws me to the landing login (welcome) page with the user clearly already logged in , here the code :
import store from '../store/index'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: Home,
beforeEnter:(to, from, next) => {
if (store.getters.getUser == null || store.getters.getUser == undefined ){
next('/welcome',)
}
else return next()
}
},
path: '/chat',
name: 'chat',
component: Chat,
beforeEnter:(to, from, next) => {
if(store.getters.getUser == null || store.getters.getUser == undefined ){
next('/welcome',)
}
else return next()
}
}...etc...
]
guess had to hard code a forced exit to this , but not so conventional or dynamic because only would put me on a specific page , no matter where of the other links by the moment i might be at ...
simply kept the beforeEnter in my router.js file , and then in the landing page, for the non authenticated users set a watcher on a opposite condition , pushing straight to home page , but the point is , being on other view aside home page , if i recharge , then would throw me to home page again....
I struggled with the beforeEach for a while , but none of possible solutions on the web was successful .
Here what i did:
router.js file
import store from '../store/index'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: Home,
beforeEnter:((to, from, next)=>{
if(store.getters.getUser == null || store.getters.getUser == undefined ){
next ('/welcome',)
}
else next ()
})
},
{
path: '/about',
name: 'about',
component:About,
},
{
path: '/chat',
name: 'ChatRoom',
component:ChatRoom,
beforeEnter:((to, from, next) => {
if(store.getters.getUser == null || store.getters.getUser == undefined ){
next ('/welcome',)
}
else next()
})
},
{
path: '/results/:idItemSelected',
name: 'SearchResults',
component:SearchResults,
props:true,
beforeEnter:((to, from, next) => {
if(store.getters.getUser == null || store.getters.getUser == undefined ){
next ('/welcome',)
}
else next()
})
},
{
path: '/welcome',
name: 'WelcomingPage',
component:WelcomingPage,
},
]
and then on my WelcomingPage view set this:
computed: {
...mapGetters(["getUser"]),
user(){
return this.$store.getters.getUser
}
watch:{
user(value) {
if(value != null||value != undefined){
this.$router.push('/')
}
else{
return this
}
},
This middly works but still isn't completely right , so please if someone has the same issue and already found a practical solution , better than this , i would appreciate any help.
Thanks in advance
I want to have a url like this /restaurants/:pageNumber and I want /restaurants to assume the pageNumber parameter is 1.
Here is my Router.js :
Router.map(function() {
this.route('restaurants', function() {});
this.route('restaurants', { path: '/restaurants/:pageNumber' }, function() {});
});
If it remove the function() {} for it, I just get a blank page with no errors in the console for /restaurants/1
My routes/restaurants/index.js :
export default Ember.Route.extend({
ajax: Ember.inject.service(),
model(params) {
return Ember.RSVP.hash({
response: this.get('ajax').request('/getAllRestaurants', {method: 'GET'}),
currentPage: params.pageNumber | 1
});
}
});
On the templates/restaurants/index.hbs I check {{model.currentPage}} and it's always 1.
Because logical OR is ||, not |. page = params.pageNumber || 1. But more reliable is ternary operator, page = (params.pageNumber !== undefined ? params.pageNumber : 1)
Did you try { path: '/restaurants/:page_number' } and
currentPage: params.page_number || 1 ?