VueJS 3 Router behaves differently in Dev and Production - javascript

I'm pretty new to VueJS and have a problem I can't grasp right now.
I coded a little App which works absolutely fine under vue serve, but when I build it and upload the dist folder to my webserver I'm experiencing a weird problem.
I have the following Routes:
/home
/overview
/listing
/detail
I start at home, click on a button go to overview, from there to listing and from there to detail. Every template has a a "Go Back" Link which works with
#click="$router.back()"
When testing locally with Vue Serve it behaves as expected.
When I built it and upload the dist folder I get the weird error that when I'm on "Detail" and go back, it goes to "Overview" instead of "listing". I notice that the address in the browser is always one level "off". For example if I go back from overview to home, it shows the home-template but the addressbar shows /listing.
Does anyone have an idea what I'm doing wrong? Thanks a lot!
I already tried $router.go(-1), which results in the same error..
My router file looks pretty standard I'd say:
{
path: '/home',
name: 'Home',
component: Home
},
{
path: '/overview',
name: 'Overview',
component: Overview
},
{
path: '/listing',
name: 'Listing',
component: Listing
},
{
path: '/detail',
name: 'Detail',
component: Detail
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
It works great in vue serve mode, but just not when using the dist folder online..

Related

opening page in new tab getting 404 error

I am trying to open page in new tab, in local it was working fine when deployed to server getting error as below:
Oops, looks like the page is lost.
This is not a fault, just an accident that was not intentional.
Below is my code:
Router:
const routes: Routes = [
{ path: ' ', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'resource', component: ResourceDetailsComponent },
{ path: 'careers', component: CareerComponent }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
In component:
<a class="view" (click)="redirect(a)"
>VIEW MORE VACANCIES</a
>
redirect(){
localStorage.removeItem("selectedCareer");
window.open("/careers", '_blank');
}
In local page is redirecting and working fine, anything i have missed in my code please let me know.
You are probably trying to access some suburl like yourhomepage.com/resource right?
Your local Development Server will always serve the index.html per default and you probably want to configure your deployment server the same way. You need the index.html file to be served for your angular spa to work. Without knowing your Provider/Server there is no real way to help you with that.
Most Webservers are configured to always return the file you are accessing through the url or the index.html if you provide no suburl.
So if your file tree looks like this:
index.html
angular.js
yourhomepage.com and yourhomepage.com/index.html will return the index.html
and yourhomepage.com/angular.js will return the js file.
BUT yourhomepage.com/ressouces will not return anything because there is no corresponding file. But you can configure your Webserver to also return the index.html in that case.
This is what you probably have to do.

Angular routing bug - this.router.navigateByUrl() and this.router.navigate()

I am creating angular application that will handle documentation for my GitHub apps, in more complex way than just readme files. I want to redirect user after clicking in topnav dropdown to selected route, but there's problem with router. (I need to redirect with some parameters, but it doesn't work even with simple path reditect). Those methods redirect to target route for like 1 seconds (like excepted), then user got redirected back to root page.
Code:
/* First element is project name, second is category/part of application name */
choices = ["typing_speed_test", "overview"]
json = json
constructor(private router: Router){}
onProjectClick($event){
this.choices[0] = $event.target.innerHTML.trim();
this.choices[1] = "overview";
this.redirect();
}
onCategoryClick($event){
this.choices[1] = $event.target.innerHTML.trim();
this.redirect();
}
redirect(){
this.router.navigateByUrl("404");
}
Routes:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'project/:project_name/:category', component: SubpageComponent },
{ path: '404', component: NotFoundComponent },
//{ path: '**', redirectTo: '404', pathMatch: 'full' }
];
Link to gif with problem: https://imgur.com/a/x2mPxvh
Full code in github repo: https://github.com/Dolidodzik/DocsForMyApps (if you used code from here to answer this question, please point that in your answer)
I think I may did some stupid mistake, because I am pretty new in Angular, but I couldn't do it, because every google question showed me solves for ERRORS, when redirect doesn't work at all, not to bugs like in my situation.
You need to remove the href="#" from your anchor links in your navigation bar. It's causing the browser to reload:
<a class="dropdown-item" *ngFor="let item of categories() | keyvalue">
{{item.key}}
</a>
Also this is a bit weird solution:
this.choices[0] = $event.target.innerHTML.trim();
You better just send the item variable in your function call in your template, and you can then read this in your component event handler:
onProjectClick(item){
this.choices[0] = item.key;
this.choices[1] = "overview";
this.redirect();
}
the problem is your lins look like this:
link
default link behavior causes your app reload from the start. you should use [routerLink]="['someUrl']" instead of href. If you need that href in some cases, consider calling $event.preventDefault() to cancel the native browser navigation

Redirect on startup by the given browser URL

I created a new Vue app with a base path. Due to the fact the app is embedded into another Vue app, this app doesn't render the router-view on startup. If you want to know more about how or why this app is embedded into another app, please have a look here:
mount Vue apps into container of main Vue app
and my own answer to this problem:
https://stackoverflow.com/a/58265830/9945420
When starting my application, it renders everything except the router-view. I want to redirect on startup by the given browser URL. This is my router config:
import Vue from 'vue';
import Router from 'vue-router';
import One from './views/One.vue';
import Two from './views/Two.vue';
Vue.use(Router);
const router = new Router({
base: '/my-embedded-app/',
mode: 'history',
routes: [
{
path: '/',
component: One,
},
{
path: '/two',
component: Two,
},
],
});
router.replace(router.currentRoute.fullPath);
export default router;
I want the app to render the component Two when calling .../my-embedded-app/two. Unfortunately, router.replace always redirects to / (so the browser URL is .../my-embedded-app/). I debugged the router, and saw that the path is /, but I would expect it to be /two.
Important note:
I don't want to redirect the user to /two whenever the url is /. I just want to render the view Two when the url is /two. Currently it doesn't.
What might be wrong? Maybe I don't even need that redirect, and can solve the problem a more elegant way.
updated: jsfiddle
What wound up happening is that route.currentRoute.fullPath was executed before router was ready.
That's the normal behavior, it is the way single page application works. The "pound" - like # - sign means that the links will not move the application to another page.
so you can change the router mode to
mode:"hash"
Try beforeEnter. Have a look at the below code:
const router = new Router({
base: "/my-embedded-app/",
mode: "history",
routes: [
{
path: "/",
component: One,
beforeEnter: (to, from, next) => {
// Your are free to add whatever logic here.
// On first visit
next("/two");
}
},
{
path: "/two",
component: Two
}
]
});
Read more about Navigation guards here
Could you provide a github repo or some to test the actual?
Otherwise my first idea is to use children routes with an "empty" view as base, here an example about what I tried. (working in my case)
router.js
export default new Router({
mode: 'history',
base: '/my-embedded-app/',
routes: [
{
path: '/',
name: 'base',
component: Base,
children: [
{
path: '',
name: 'one',
component: One
},
{
path: 'two',
name: 'two',
component: Two
}
]
}
]
})
Base.vue
<template>
<router-view/>
</template>
One.vue
<template>
<div>One</div>
</template>
Two.vue
<template>
<div>Two</div>
</template>

Angular2/4 independent Login Page

I'm building a site with MEAN stack, and overall this is my structure:
root
app
auth
auth.routes.ts
auth.service.ts
app.component.html
app.component.ts
app.routing.ts
On my app.routung.ts I have this code:
const APP_ROUTES: Routes = [
{ path: '', redirectTo: '/main_url', pathMatch: 'full' },
{ path: 'main_url', component: MainComponent, canActivate: [AuthenticationGuard] },
{ path: 'cars', component: CarsComponent },
{ path: 'auth', component: AuthenticationComponent, children: AUTH_ROUTES },
];
Then, in my app.js main file I have these routes:
app.use('/main_url', mainRoutes);
app.use('/cars', carRoutes);
app.use('/', appRoutes);
The content of appRoutes is this:
var express = require('express');
var router = express.Router();
router.get('/', function (req, res, next) {
res.render('index');
});
module.exports = router;
The index file, renders an html with a menu on the left sidebar. In the content part, I have a <my-app>Loading...</my-app>, which loads the app.component.ts and all the logic there.
The question here is, how can I secure my index.html main route, with a login page, when I don't want to include it inside my <my-app>Loading...</my-app>?
I'm I doing something wrong? Or there is a good way to do that?
UPDATE
A brief description of my problem:
I have a node router, which only has a get method, then, is redirected to index:
... code ...
res.render('index');
index.html, is a template with a header, sidebar menu, footer and content. In the content, I have this: <my-app>Loading...</my-app>, this line triggers my angular component, which uses my Angular Routes (APP_ROUTES), the one I posted before.
All at this point works fine, but, how can I prevent to trigger the index.html from my res.render('index'), when the user is not logged in and send it to a complete separated login.html page/code? I think I have to change something because always I'm going to be redirected to index, no matter what, because it is the entry point.
Please try Angular's HashLocationStrategy, which puts a '#' in the URL to separate the bit's the server responds to from the bits Angular responds to (to put it crudely).
Ng-book gives a good description, the essentials are
import {LocationStrategy, HashLocationStrategy} from '#angular/common';
#NgModule({
declarations: [
...
],
imports: [
...
],
providers: [
provide(LocationStrategy, {useClass: HashLocationStrategy})
]
Please also see the answer to this SO question, which mentions server configuration (as an alternative).
Ensure your server is configured to support HTML5 pushState. This just
means that the server returns index.html for requests to unknown
resources.
Here is another good reference Location Strategies in Angular Router, probably the best I can find to describe the problem.

Angular 2 Routing exception

Worked on my project 3d ago. after that just pushed it into my repo.
Today i cloned repo and install dependencies.
If early it worked good today i have bunch of errors.
When i trying to get sell <a routerLink="/sell">Sell</a> page by url -> localhost:3000/sell
const appRoutes: Routes = [
{
path: '',
component: MainPageComponent
},
{
path: 'sell',
component: SellComponent }
];
I'm getting this error
error image
Note: It worked till this day.
Thanks for help
You should add , pathMatch: 'full' to the first (empty path) route though if it is not a redirect and doesn't have child routes.

Categories

Resources