I am working through this tutorial:
https://www.digitalocean.com/community/tutorials/how-to-navigate-between-views-with-vue-router#conclusion
Eventually it is possible to call a specific airport via a link like this: http://127.0.0.1:5173/airports/cvg and some more details via http://127.0.0.1:5173/airports/cvg/destinations
Close to the end of the aforementioned tutorial a fallback call to a 404 page is implemented, should the route not exist, e.g. this should redirect to 404:
http://127.0.0.1:5173/airports/cvgTHIS_DOES_NOT_EXIST
The routes look like this:
const routes = [
{
path: '/',
name: 'Home',
component: () => import('#/pages/HomePage.vue'),
},
{
path: '/about',
name: "About",
component: () => import('#/pages/AboutPage.vue'),
},
{
path: '/airports',
name: "Airports",
component: () => import('#/pages/AirportsPage.vue'),
},
{
path: '/airports/:code',
name: "AirportDetail",
component: () => import('#/pages/AirportDetail.vue'),
children: [
{
path: 'destinations',
name: 'AirportDestinations',
component: () => import('#/pages/AirportDestinations.vue'),
}
]
},
{
path: '/:catchAll(.*)*',
name: 'PageNotFound',
component: () => import('#/pages/PageNotFound.vue')
}
]
The fallback call to 404 is implemented in AirportDetail.vue's onMounted using the route's name property:
[...]
const airport = computed(() => {
return airports.filter(a => a.abbreviation === route.params.code.toUpperCase())[0]
})
onBeforeMount(() => {
if (!airport.value) {
router.push({ name: 'PageNotFound' })
}
})
However, I get warnings and errors like these:
runtime-core.esm-bundler.js:38 [Vue warn]: Unhandled error during execution of render function
at <AirportDetail onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >
at <RouterView>
at <App>
warn2 # runtime-core.esm-bundler.js:38
[...]
runtime-core.esm-bundler.js:38 [Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core
at <AirportDetail onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >
at <RouterView>
at <App>
AirportDetail.vue:3 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'name')
at Proxy._sfc_render (AirportDetail.vue:3:20)
[...]
Here is a codesandbox:
https://codesandbox.io/s/sweet-roentgen-idg8yf
and the github repo:
https://github.com/rowild/vue3-airports-tutorial
Calling 404 works in all other cases, just not in this one. Any idea why router.push(...) is not working in this particular case?
As it turns out, in AirportDetail.vue I need to check if the route's parameter returns a result from the airports.json and therefore implement a v-if="!airport.abbreviation". Then the warnings and errors will not happen.
Related
I created dynamic routes and locally it works perfectly, but when I publish the application it is returning
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.
index-d9e4afe8.js:9 TypeError: Failed to fetch dynamically imported module: http://host/sistem/views/reports/reportSales.vue
/sistem/home:1 Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://host/sistem/views/reports/reportSales.vue
this is my routes index.js structure
import { createRouter, createWebHistory } from "vue-router";
import TopMenu from "../layouts/top-menu/Main.vue";
import Login from "../views/admin/login/Main.vue";
import Home from "../views/admin/home/Main.vue";
import Exit from "../views/admin/exit/Main.vue";
import hosts from "#/utils/hosts";
async function createRouterInstance() {
var data = await searchRoutes();
let lstRoutes = [
{
path: `${hosts.app}` + "/home",
name: "Home",
component: Home,
},
{
path: `${hosts.app}` + "/exit",
name: "Exit",
component: Exit,
},
];
for (var i = 0; i < data.length; i++) {
let dsPath = `${hosts.app}/${data[i].pagename}`;
let pathComponent =
"../views/" + data[i].path + "/" + data[i].pagename + ".vue";
lstRota.push({
path: dsPath,
name: data[i].pagename,
component: () => import(pathComponent),
});
}
let routes = [
{
path: `${hosts.app}/`,
name: "Login",
component: Login,
},
{
component: TopMenu,
children: lstRota,
},
];
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
return savedPosition || { left: 0, top: 0 };
},
});
return router;
}
export default await createRouterInstance();
previously I had vite 2, but researching the error, I updated to vite 4.0.0-alpha.6 and the same error continued, I also tested changing to createHashWebHistory in my route, but the same error also occurs and why I also tried importing without the .vue extension, but it still persists
I have this route that has a children. I can retrieve the name of the route however it is only applicable to the name of the children.
const routes = [
{
path: '/',
name: 'Home', // <--- I want to get this route name
component: () => import('layouts/MainLayout.vue'),
children: [
{ path: '', component: () => import('src/pages/Home/Index.vue') },
{ path: '/patient', component: () => import('src/pages/Home/Patient.vue') },
]
},
{
path: '/auth',
name: 'Auth', <--- I want to get this route name
component: () => import('layouts/AuthLayout.vue'),
children: [
{ path: '', component: () => import('pages/Login.vue') },
//{ path: '', component: () => import('pages/Login.vue') }
]
},
// Always leave this as last one,
// but you can also remove it
{
path: '/:catchAll(.*)*',
component: () => import('pages/Error404.vue')
}
]
export default routes
Then I tried remove all named routes from the children and assigned a name to the parent but it gives me
undefined whenever I console.log($route.name) on the MainLayout.vue
I'm not sure if this is really the right way of getting the parent's route name but I have achieved it using route.matched
import { useRoute } from 'vue-router'
...
const path = computed(() => $route.matched[0].name ) //[0] first one
This should return the component name Home
I think you're looking for the immediate parent of the current active route .. yes?
In that case, you do as previously mentioned use this.$route.matched, but not as stated. The current route is the last item in $route.matched array, so to get the immediate parent you can use:
const parent = this.$route.matched[this.$route.matched.length - 2]
const { name, params, query } = parent
this.$router.push({ name, params, query })
In my vue.js 3 project I am using vite-plugin-pages and for some reason #Shulz's solution gives me route.matched[0].name: undefined. So, doing things as mentioned below helped:
In <template>
<router-link to='/the-page' :class='{ "active": subIsActive("/the-page") }'> The Page </router-link>
In <script>
const subIsActive = (input) => {
const paths = Array.isArray(input) ? input : [input];
return paths.some((path) => route.path.indexOf(path) === 0);
};
but, as I am using vite-plugin-pages I found another solution and I followed this approach to fix my issue.
I have an Angular app version update from 8 to 11. This router is not working after the update. Show blank page when application is run. There is no error in the compilation and browser consoles. How to solve the problem?
export const AppRoutes : Routes = [
{ path: 'login', component: LoginPageComponent }
{ path: '', component: MainComponent},
{ path: '', component: MainComponent, children: [
{ path: 'test-one', loadChildren: () => import('./TestOne/TestOne.module').then(m => m.TestOneModule)},
{ path: 'test-two', loadChildren: () => import('./TestTwo/TestTwo.module').then(m => m.TestTwoModule), canActivate: [AuthGuard], runGuardsAndResolvers: 'always'}
]},
{ path: ':pageslug', component : MainComponent },
{ path: '**', component : MainComponent }
];
There are some breaking changes concerning router in Angular 11 as follows:
router: * The initialNavigation property for the options in RouterModule.forRoot no longer supports legacy_disabled, legacy_enabled, true, or false as valid values. legacy_enabled (the old default) is instead enabledNonBlocking
enabled is deprecated as a valid value for the RouterModule.forRoot initialNavigation option. enabledBlocking has been introduced to replace it
router: preserveQueryParams has been removed, use queryParamsHandling=”preserve” instead
router: If you were accessing the RouterLink values of queryParams, fragment or queryParamsHandling you might need to relax the typing to also accept undefined and null. (#39151)
Pls see :
https://medium.com/swlh/angular-11-in-depth-9a7372b4a600
Child Module
const routes: Routes = [
{ path: '', component: ProcComponent,
children:[{
path: '/LoadProcResultsdata/:procResults', component: ProcResultsComponent,
}]
}
];
App.Module.ts
const routes: Routes = [
{ path: 'app', component: AppComponent },
{ path: 'home', component: HomeComponent },
{ path: 'treeview', component: TreeViewComponent },
{path:'Proc', loadChildren:'app/proc/Proc.Module#ProcModule'}
];
My code
this.router.navigate(['/LoadProcResultsdata/'],{ queryParams: { procResults:this.results } });
But I am getting following error.
core.umd.js:3064 EXCEPTION: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'LoadProcResultsdata'
Error: Cannot match any routes. URL Segment: 'LoadProcResultsdata'
There are couple of issues,
remove front / from the path,
children:[{
path: '/LoadProcResultsdata/:procResults', component: ProcResultsComponent,
}]
Also you need to use route params rather query params, so you can use below,
this.router.navigate(['/LoadProcResultsdata', this.results]);
I am assuming this.results is some ID, so the resulting url becomes
/LoadProcResultsdata/<id>
Read more abour route parmeters here.
Update:
you can do that but not with route params, just with queryParams, remove :procResults, and use similar code like below,
let extra: any = ['abc','xyz'];
let navigationExtras: NavigationExtras = {
queryParams:extra
};
this.router.navigate(['/LoadProcResultsdata'],navigationExtras);
and in the navigted component subscribe to ActivatedRoute queryParams,
constructor( private route: ActivatedRoute) {
route.queryParams.subscribe(params => {
console.log(params);
})
}
Check this Plunker!!
another Plunker with Lazy loaded module.
I have just upgraded from router-deprecated to "#angular/router": "3.0.0-alpha.8". I have everything working inside the application but it's not working when I navigate to a URL.
For example, I use this routerLink:
<a [routerLink]="['/app/dashboard']">DashBoard</a>
which produces this URL:
http://localhost:54675/app/dashboard
And that view loads with no problem.
However, if I just enter that URL in the browser and press return I get a blank white page. Nothing in the console and the source is empty.
I am using the default HTML5 locationStrategy - not the hash (#).
This worked with router-deprecated.
I can't figure out what I could be doing wrong since everything else is working.
When I navigate to a fill URL I notice that I get a 404 error in the console. That's because nothing on the server matches this URL, but it needs to load the app then route to that URL.
Here are my route files:
app.routes.ts:
export const routes: RouterConfig = ([
{ path: '', component: SplashComponent },
{ path: 'login', component: SplashComponent },
...MainRoutes
]);
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];
main.routes.ts
export const MainRoutes: RouterConfig = [
{
path: 'app',
component: MainLayoutComponent,
children: [
{ path: 'dashboard', component: DashboardComponent},
{ path: '', component: DashboardComponent },
{ path: 'user', component: AccountEditComponent },
{ path: 'admin', component: ManageComponent }
]
}
];
My Angular2 app was hosted in an DotNet Core application. I had to configure it to redirect to index.html on URLs that returned 404s. I followed this article:
http://asp.net-hacker.rocks/2016/04/04/aspnetcore-and-angular2-part1.html