Bootstrap JS stops working after route change in Angular 5 - javascript

I am using Angular 5, and Bootstrap 4. I have bootstrap installed as an npm module, and it is set up in my angular-cli scripts and style portions. I essentially only have two routes in this application. A login route, and a table view route.
scripts": [
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/popper.js/dist/umd/popper.min.js",
"../node_modules/tether/dist/js/tether.min.js",
"../node_modules/bootstrap/dist/js/bootstrap.min.js",
"libs/pjd-design-system-core/dist/scripts.min.js"
],
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"../node_modules/font-awesome/css/font-awesome.css",
"theme.scss",
"styles.scss",
"libs/pjd-design-system-core/css/pjd-icons.css"
],
I have noticed that when I leave the login route, and go to the table view route the JS portion of bootstrap no longer works. I have tested this by taking the dropdown component code from the bootstrap 4 website and pasting it into my login component and my table view component. In the login the dropdown opens, but in the table view the dropdown does not.
Other relevant information.
Angular Version: 5.2.0
Angular-CLi Version: 1.7.3
Edit:
What I expect to happen is once I change routes that any bootstrap element that requires javascript will still function. What currently happens is that once I change routes, and a new component is loaded (read once I leave the landing page, and go to the table view page) any bootstrap element that requires javascript to function (such as a dropdown menu) no longer functions (the dropdown will no longer open when clicking on it). Currently I am receiving no errors.
Included router module code
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { PayEstimateFormComponent } from './pay-estimate-form/pay-estimate-form.component';
import {SigninComponent} from './auth/signin/signin.component';
import {AuthGuard} from './auth/auth-gaurd.service';
const routes: Routes = [
{path: '', redirectTo: '/payEstForm', pathMatch: 'full'},
{path: 'login', component: SigninComponent},
{path: 'payEstForm', component: PayEstimateFormComponent, canActivate: [AuthGuard]},
];
#NgModule({
imports: [RouterModule.forRoot(routes, {useHash: true})],
exports: [ RouterModule ],
})
export class AppRoutingModule { }

Related

how to bundle a module/component to js and use in another angular project?

I was just trying to build a module/component and serve it as a JS bundle. it builds:
#Component({
selector: 'app-component-overview',
template: '<button><ng-content></ng-content></button>',
})
export class ButtonComponent {}
#NgModule({
declarations: [ButtonComponent],
})
export class AppModule {}
the issue is that after building it to a javascript bundle. when I try to import it in another angular project. I get:
//ERROR in ... error TS2306 '...' is not a module.
loadChildren: () => import('...').then(m=>m.ButtonModule)
maybe I am missing the point here and things are different in angular, having webpack control makes it a lot easier but I want to avoid bringing custom builders and fiddling with the settings as little as possible.
Question is, is there a well documented way to bundle a module or even a standalone component to be used outside my project as a JS bundle? I could not find anything useful other than high level explanation of reusing and lazyloading thing already inside the same project.
It seems you are building this module as part of an application which is supposed to run in a browser. But what you are looking for is to build this module as part of a library which can be re-used in other projects.
See this official Angular guide on how to create a library.
After a few hours browsing around. I figured it out.
The answer that #json-derulo gave is part of the solution but there are more steps to make this work.
follow the guide: https://angular.io/guide/creating-libraries
here is the tricky part if you import the lib inside the workspace it will work. but that does not make much sense. You likely have another repository with a angular app that you want to consume the lib.
now to be able to import the this component as a lazy loaded route you will need to add "#angular/router" to the lib peerDependecies and run npm install again
now create a routing module and add the empty path to point to the component in the lib.
//my-lib-routing.module.ts
import { NgModule} from "#angular/core";
import { RouterModule } from "#angular/router";
import { MyLibComponent } from "./my-lib.component";
const routes= [
{ path: '', component: MyLibComponent },
];
#NgModule({
imports: [
RouterModule.forChild(
routes,
)
// other imports here
],
// providers: [RouterModule],
exports: [RouterModule]
})
export class myLibRoutingModule { }
change the libmodule to import the routing module
//
import { NgModule } from '#angular/core';
import { myLibRoutingModule } from './my-lib-routing.module';
import { MyLibComponent } from './my-lib.component';
#NgModule({
declarations: [MyLibComponent],
imports: [
myLibRoutingModule
],
})
export class MyLibModule { }
on the lib project root run 'npm run build'.
create a separate repo and "ng new app"
add the lib to the package.json of the main app, something like "my-lib": "../my-lib-ws/dist/my-lib".
open angular.json and add "preserveSymlinks": true to the build options.
run npm i to link the lib as a dependency.
add the libmoudle as a lazy loaded route
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{path: 'test', loadChildren: () => import('my-lib').then(m=>m.MyLibModule)}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
run npm run start. and try to access the 'test' route. you should see the component loaded in the main app router outled
Now, this is more of learning exercise the bundles almost gets doubled. and you would profit more using module federation. But it is a use case we have. Anyhow the steps are here if anyone can't reproduce let me know.

Multiple named router-outlet - component imported but not initialized and rendered

I'm using multiple named angular 8 router-outlet in a web app. All the routerLink seems to work as it changes the URL but components in my 2nd router-outlet are imported but not initialized nor rendered.
I made a Stackblitz available here : https://stackblitz.com/edit/ng-multiple-router-outlet?file=src/app/app.component.ts
As you can see, when you click on the sidebar, under photos you have a second navigation level by clicking on Google or Facebook but nothing is rendered.
In modules, components used in other modules and RouterModule are well exported to be accessible, I don't see what I've done wrong.
I tried to declare the routes with both forRoot and forChild methods, I put some logs, but I'm running out of clues.
Thanks for your help !
Angular router is pretty simple once you understand how nested routes works there.
Let's imagine a simple configuration:
RouterModule.forRoot([
{
path: '',
component: HomeComponent,
children: [
{ path: 'child', component: ChildComponent }
]
}
])
How would you use router-outlet to cover all routes above?
app.component.html
\
contains
\
<router-outlet></router-outlet>
\/
renders
\
HomeComponent
home.component.html
\
contains
\
<router-outlet></router-outlet>
renders
\
ChildComponent
The main takeaway here is that router-outlet renders component depending on router context. Once it renders component a new context is created and all router-outlet's declared at this level will look at children configuration.
The same is true for named routes.
You've generated the link like:
(selection:facebook//sidebar:photos)
It means that these named routes should be at the same root level. But you defined <router-outlet name="selection"></router-outlet> at nested level inside rendered by router LibraryComponent.
Let's add this outlet at the same level as 'sidebar':
<router-outlet name="sidebar"></router-outlet>
<router-outlet name="selection"></router-outlet>
and it actually works stackblitz
Now let's come back to your attempt. If you want to render selection components inside selection.component.html then you should be using nested named routed links:
selection.component.html
[routerLink]="['.', { outlets: { selection: [routeName] } }]"
\/
relative path
The above binding will generate nested links like (sidebar:photos/(selection:facebook))
Now you need to move SelectionRoutes configuration to children property of photos path:
selection.module.ts
imports: [
CommonModule,
RouterModule, //.forChild(SelectionRoutes)
],
sidebar.routes.ts
import { SelectionRoutes } from '../selection/selection.routes';
...
export const SidebarRoutes: Route[] = [
{ path: 'photos', component: LibraryComponent, outlet: 'sidebar', children: SelectionRoutes },
Stackblitz Example
Update
In order to make facebook as a default subroute you create a route with redirectTo option like:
export const SelectionRoutes: Route[] = [
{ path: 'facebook', component: FacebookComponent, outlet: 'selection' },
{ path: 'google', component: GoogleComponent, outlet: 'selection' },
{ path: '', redirectTo: '/(sidebar:photos/(selection:facebook))', pathMatch: 'full', },
]
Stackblitz Example

Angular navigating from AppComponent to another Component

I have the following setup:
in app-routing module:
export const routes: Routes = [
{ path: '', component: AppComponent },
{ path: 'Role', component: RoleComponent }
];
In app.module.ts, I have:
imports: [
RouterModule.forRoot(routes)
],
In app.component.html, I have
Test
view above is an iframe. However, it doesn't find the role component to go to role.component.html page and open it in iframe.
BTW, role component files are in a folder called role under app directory where the app.component.html is.
app > app.component.html, ts, css
app > role > role.component.html, ts, css
And obviously everything compiles fine in VS Code.
Any ideas whats missing?

Routing in angular disables javascript functions

I have a simple angular routing module that looks like this:
import { NgModule, ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './../../home/home.component';
import { LoginComponent } from './../../login/login.component';
const routes: Routes = [
{
path: '',
component: HomeComponent
},
{
path: 'login',
component: LoginComponent
}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
The HomeComponent is loaded at first whenever I open the page. everything works fine until I switch to the login page. Both of them have certain parts that work with javascript. I added those in the .angular-cli.json file.
If I switch to the login page using the following button:
<li class="active"><a routerLink="">Home</a></li>
none of those functions seem to work, also whenever I switch back to the homepage component, the functions that did work before won't work here either.
So far i found out that the scripts are loaded once since the main application is loaded using "eager loading" and the compontens use "lazy loading".
Is there a way to load the scripts again or any other way to fix this?
I managed to fix the problem by using the solution given on the following page:
how to load js on component level in angular 4. I don't want to load all js file at app startup
given by Milad.

how to make separate module in angular 2?

could you please how to make separate module in angular 2 ?I make a simple example of angular in which user on button click show second page. But now I want to move my code in separate module in angular where I will write separaterouting and components
I try like this
https://plnkr.co/edit/Vm4OXXCCqCI0uTvGdORn?p=preview
I make separate module and routing file
const routes =[
{
path: 'sd',
component: Second
},
{
path: '**', redirectTo: ''
}
]
module file
#NgModule({
imports: [RouterModule.forChild(routes)],
declarations: [ Second],
})
export class SecondModule {}

Categories

Resources