I have browsed the other similar posts on stackoverflow, but have not found one that helps my cause, so here goes:
I am using angular2 based on the webpack "boiler-plate" from angular.io and included the routing bit.
I end up with this error even though the current setup is extremely minimal:
Unhandled Promise rejection: Template parse errors:
'Mathador' is not a known element:
1. If 'Mathador' is an Angular component, then verify that it is part of this module.
...
Here are the relevant code fragments
app/app.html
<main>
<h1>Mathador prototype</h1>
<router-outlet></router-outlet>
</main>
**app/app.routes.ts**
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent } from './pages/home/home'
const appRoutes: Routes = [
{
path: '', component: HomeComponent
}
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
**app/app.ts**
import { Component } from '#angular/core';
import '../../public/css/styles.css';
#Component({
selector : 'my-app',
templateUrl : './app.html',
styleUrls : ['./app.scss']
})
export class AppComponent {
}
**app/app.module.ts**
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { routing } from './app.routes';
// core
import { AppComponent } from './app';
// pages
import { HomeComponent } from './pages/home/home';
// components
import { Mathador } from './components/mathador/mathador';
#NgModule({
imports: [
BrowserModule,
routing
],
declarations: [
AppComponent,
HomeComponent,
Mathador
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
**app/pages/home/home.ts**
import { Component } from '#angular/core';
#Component({
selector : 'my-home',
templateUrl : './home.html',
styleUrls : ['./home.scss']
})
export class HomeComponent {
constructor() {
// Do stuff
}
}
**app/pages/home/home.html**
<h1>home!</h1>
<Mathador></Mathador>
**app/components/mathador.html**
<div>transclusion succesfull!</div>
**app/components/mathador.ts**
// Importing core components
import {Component} from '#angular/core';
#Component({
selector : 'mathador',
templateUrl : './mathador.html'
})
export class Mathador {
constructor() { }
}
Related
Right now I would like now how to set the name of a route in angular like Vue as I don't want to get the "path" but the alias, the same way as can be done in vue.
This is my app-routing.module.ts
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { LanguagesComponent } from './languages/languages.component';
const routes : Routes = [
{path : 'login',component:LoginComponent},
{path : 'languages',component:LanguagesComponent, name:"languages.index"}, //Set the name to route as can be done in vue
{path : 'unauthorized',component:UnauthorizedComponent}
]
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Then I want to get the route name since a service in angular.
This is my sevice File:
import { LocationStrategy } from '#angular/common';
import { Injectable } from '#angular/core';
import { Router } from '#angular/router';
#Injectable({
providedIn: 'root'
})
export class PermissionByRoleService {
constructor(public router: Router,private location: LocationStrategy){}
get permissionByRole(): boolean {
if(this.getCurrentRouteName()=="languages.index"){
return true;
}
return false;
}
getCurrentRouteName(){
console.log(this.location.path() ); //Get '/languages'
console.log(this.router.url ); // I'm supposed to get '/languages' but I get '/'
console.log();// How get route name something Similar To Vue
return this.router.url ; // I neeed return route name according to porpierties of routes
}
}
Would it be possible to do this?
If so.
How can I do this?
I appreciate any help
I've been trying to create a language localization app in Ionic. The idea is to setup the translation service in the app.component (to make it available throughout the app) and then use it in a tab (for ex: tab2.html).
I receive an error as follows:
TypeError: this.http.get is not a function
at TranslateHttpLoader.push../node_modules/#ngx-translate/http-loader/fesm5/ngx-translate-http-loader.js.TranslateHttpLoader.getTranslation (ngx-translate-http-loader.js:27)
at TranslateService.push../node_modules/#ngx-translate/core/fesm5/ngx-translate-core.js.TranslateService.getTranslation (ngx-translate-core.js:738)
at TranslateService.push../node_modules/#ngx-translate/core/fesm5/ngx-translate-core.js.TranslateService.retrieveTranslations (ngx-translate-core.js:713)
at TranslateService.push../node_modules/#ngx-translate/core/fesm5/ngx-translate-core.js.TranslateService.setDefaultLang (ngx-translate-core.js:629)
at new AppComponent (app.component.ts:18)
at createClass (core.js:22062)
at createDirectiveInstance (core.js:21931)
at createViewNodes (core.js:23157)
at createRootView (core.js:23071)
at callWithDebugContext (core.js:24079)
Ionic info is as follows:
ionic (Ionic CLI) : 4.9.0
ionic Framework : #ionic/angular 4.0.0
#angular-devkit/build-angular : 0.12.3
#angular-devkit/schematics : 7.2.3
#angular/cli : 7.2.3
#ionic/angular-toolkit : 1.2.3
System:
NodeJS : v10.15.0 (C:\Program Files\nodejs\node.exe)
npm : 6.4.1
OS : Windows 10
The code files are as below.
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule, HttpClient } from '#angular/common/http';
import { TranslateModule, TranslateLoader } from '#ngx-translate/core';
import { TranslateHttpLoader } from '#ngx-translate/http-loader';
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http);
}
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy}
],
bootstrap: [AppComponent]
})
export class AppModule {}
app.component.ts
import { Component } from '#angular/core';
import { Platform } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { TranslateService } from '#ngx-translate/core';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent {
constructor(
private translate: TranslateService,
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar
) {
translate.setDefaultLang('en');
this.initializeApp();
}
switchLanguage(language: string) {
this.translate.use(language);
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
}
tab2.module.ts
import { IonicModule } from '#ionic/angular';
import { RouterModule } from '#angular/router';
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { Tab2Page } from './tab2.page';
import { AppComponent } from './../app.component'
import { TranslateModule } from '#ngx-translate/core';
#NgModule({
imports: [
IonicModule,
CommonModule,
FormsModule,
RouterModule.forChild([{ path: '', component: Tab2Page }]),
TranslateModule.forChild()
],
declarations: [Tab2Page]
})
export class Tab2PageModule {}
tab2.page.html
<ion-header>
<ion-toolbar>
<ion-title>
Tab Two
</ion-title>
<ion-content>
<h1 translate> Title </h1>
<div>
{{ 'Intro' | translate:user }}
</div>
<button (click)="switchLanguage('en')">en</button>
<button (click)="switchLanguage('hn')">hn</button>
</ion-content>
en.json
{
"Title": "Translation example",
"Intro": "Hello I am Arthur, I am 42 years old."
}
The expected result is The browser page for tab2 should have the text and 2 buttons for the language selection. On clicking, the text should get altered as expected. I am working on Ionic and Angular for the very first time and do not have a good grasp on how the syntax or general flow works. If the code has multiple errors, please let me know. Any help would be appreciated!
If you need access to a function from several places, consider putting it in a service.
I was unable to replicate the issue you mentioned using your code. However, I have created a sample application considering your requirements. You can follow it here
https://stackblitz.com/edit/internationalization-example
Explanation below
I have created a service
event-provider.service
import { EventEmitter } from '#angular/core';
export class EventProvider {
// Use currentLang to subscribe to the change event
public currentLang: EventEmitter<string> = new EventEmitter();
//Call this method from other components or pages to Change the language
setLang(val) {
this.currentLang.emit(val);
}
}
I'm consuming the created service in two places,
tab2.page.ts
export class Tab2Page implements OnInit {
constructor(private translate: TranslateService,private
eventProvider:EventProvider) { }
ngOnInit() {
}
switchLanguage(language: string) {
this.eventProvider.setLang(language);
}
}
app.component.ts
//Subscribe to language change in app component
this.eventProvider.currentLang.subscribe(lang => {
this.translate.use(lang);
});
Hope this helps.
I am new to Angular2. I am trying to create routes as given here.
I created three components like HeaderComponent, SidebarComponent and UiElementsComponents. All of these are declared in main.module file (root module). Everything works great till now. But when I define routes it stops from displaying anything. Even doesn't display any error. Here is my code.
main.module.ts
//Main (root) module of App is defined here.
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { BrowserModule } from '#angular/platform-browser';
import { MainComponent } from './../components/main.component';
import { HeaderComponent } from './../components/header.component';
import { SidebarComponent } from './../components/sidebar.component';
import { UiElementsComponent } from './../components/ui-elements.component';
const routes: Routes = [
{ path: '', redirectTo: '/test', pathMatch: 'full' },
{ path: 'test', component: UiElementsComponent},
];
// The root module of the pratham app.
#NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(routes)
],
declarations: [
MainComponent,
HeaderComponent,
SidebarComponent,
UiElementsComponent
],
bootstrap: [ MainComponent ]
})
export class MainModule { }
main.component.ts
//Main (root) component of Pratham is defined here.
import { Component } from '#angular/core';
#Component({
selector: 'prtm-main',
template: `<div class="prtm-wrapper">
<prtm-header-section></prtm-header-section>
<div class="prtm-main">
<prtm-sidebar-section></prtm-sidebar-section>
<router-outlet></router-outlet>
</div>
</div>`
})
export class MainComponent { }
I have already wasted hours on finding out the issue. Can you please tell me what am I missing?
I'm trying to get my head around Angular 2 (RC5) lazy-loading of modules by building a basic structure of a site with two sections, welcome and backend (think login page and main site). I've set it up following the Angular 2 docs on feature modules, one for the welcome section and one for the backend. It correctly defaults to the welcome component but my button in the welcome component that's supposed to link to the 'backend' route goes to 'welcome/backend' instead. Typing in the url with just /backend goes to /backend/welcome. Here's my app.routing.ts file:
import { Routes, RouterModule } from '#angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'welcome', pathMatch: 'full'},
{ path: 'backend', loadChildren: 'app/backend/backend.module' }
];
export const routing = RouterModule.forRoot(routes);
And my welcome.routing.ts:
import { RouterModule } from '#angular/router';
import { WelcomeComponent } from './welcome.component';
export const routing = RouterModule.forChild([
{ path: 'welcome', component: WelcomeComponent}
]);
And my welcome.component.ts:
import { Component } from '#angular/core';
#Component({
template: `
<h2>Welcome</h2>
<nav><a routerLink="backend">Login</a></nav>
`
})
export class WelcomeComponent { }
Anyway, here's plunk of the whole app to make it easier Plunkr. The ones that matter are in welcome and backend folders. Clicking Login should show Backend with a Logout button which takes you back to the Welcome page.
Any suggestions would be appreciated.
There were quite a few things wrong with your plunkr. Here is the working example https://plnkr.co/edit/QciaI8?p=preview
The router link was moved to app.component
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<h1>Module Test</h1>
<nav><a routerLink="../backend">Logins</a></nav>
<router-outlet></router-outlet>
`
})
export class AppComponent { }
You also need backend.routing.ts
import { Routes,
RouterModule } from '#angular/router';
import { BackendComponent } from './backend.component';
const routes: Routes = [
{ path: '', redirectTo: 'backend', pathMatch: 'full'},
{ path: 'backend', component: BackendComponent }
];
export const routing = RouterModule.forChild(routes);
Backend.module was changed to
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { BackendComponent } from './backend.component';
import { routing } from './backend.routing';
#NgModule({
imports: [ routing ],
declarations: [ BackendComponent ]
})
export default class BackendModule { }
I finally go it working by figuring out that router stacks routes from nested modules (e.g. 'backend' route in app.routing and 'backend' in backend.routing results in '/backend/backend' as the url). So the solution was to have a backend.routing.ts with a single route of { path: '', component: BackendComponent }. It was also necessary to add a / to the routerLink values (e.g. /backend instead of backend). Here's my final backend.routing.ts:
import { Routes, RouterModule } from '#angular/router';
import { BackendComponent } from './backend.component';
const routes: Routes = [
{ path: '', component: BackendComponent }
];
export const routing = RouterModule.forChild(routes);
And backend.module.ts:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { BackendComponent } from './backend.component';
import { routing } from './backend.routing';
#NgModule({
imports: [ routing ],
declarations: [ BackendComponent ]
})
export default class BackendModule { }
welcome.component.ts:
import { Component } from '#angular/core';
#Component({
template: `
<h2>Welcome</h2>
<nav><a routerLink="backend">Login</a></nav>
`
})
export class WelcomeComponent { }
backend.component.ts
import { Component } from '#angular/core';
#Component({
template: `
<h2>Backend</h2>
<nav><a routerLink="welcome">Logout</a></nav>
`
})
export class BackendComponent { }
This resulted in the login button taking me to /backend and the logout button taking me to /welcome as expected. Here's a link to the plunk: Plunker
I have a simple application which loads material design Ui through Appcomponent. I need to Authenticate the user before the app component is loaded.
The app component is as follows
import {Component} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES,CanActivate} from 'angular2/router';
import {AuthHttp,AuthConfig, tokenNotExpired, AUTH_PROVIDERS} from 'angular2-jwt';
import {HomeComponent} from '../home/HomeComponent'
import {AboutComponent} from '../about/AboutComponent'
import {HeaderComponent} from './HeaderComponent'
import {LoginComponent} from '../login/LoginComponent'
import {AuthService} from '../../services/AuthService'
import {SidebarComponent} from './SidebarComponent'
import {DashboardComponent} from './DashboardComponent'
import {MDL} from './MaterialDesignLiteUpgradeElement';
#RouteConfig([
{path: 'app/home', component: HomeComponent, as: 'Home'},
{path: 'app/dashboard', component: DashboardComponent, as: 'Dashboard'},
{path: 'app/about', component: AboutComponent, as: 'About'},
{path: 'app/login', component: LoginComponent, as: 'Login'},
{path: 'app/*', redirectTo: ['Login']} // this redirect is not working for some reason
])
#Component({
selector: 'my-app',
/*template: '<router-outlet></router-outlet>',*/
template: `
<body>
<div class="demo-layout mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
<app-header mdl class="demo-header mdl-layout__header mdl-color--grey-100 mdl-color-text--grey-600"></app- header>
<app-sidebar class="demo-drawer mdl-layout__drawer mdl-color--blue-grey-900 mdl-color-text--blue-grey-50">
</app-sidebar>
<main class="mdl-layout__content mdl-color--grey-100">
<router-outlet></router-outlet>
</main>
</div>
<script src="https://code.getmdl.io/1.1.3/material.min.js"></script>
</body>
`,
/*styleUrls: ['../app/assets/styles.css'], */
directives: [ROUTER_DIRECTIVES,SidebarComponent,HeaderComponent,MDL],
providers: [AUTH_PROVIDERS,AuthService]
})
export class AppComponent {
constructor() {}
}
I have a login component which logs in the user as follows
import {Component} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {AuthHttp,AuthConfig, tokenNotExpired, AUTH_PROVIDERS} from 'angular2-jwt';
import {AuthService} from '../../services/AuthService'
#Component({
selector: 'protected',
template: '',
directives: [ROUTER_DIRECTIVES],
providers: [AUTH_PROVIDERS,AuthService]
})
export class LoginComponent {
constructor(private auth: AuthService) {
this.auth.login();
}
login() {
this.auth.login();
}
logout() {
this.auth.logout();
}
static loggedIn() {
return tokenNotExpired();
}
}
The login component uses the AuthService
AuthService
import {Injectable} from 'angular2/core';
import {ROUTER_DIRECTIVES, Router} from "angular2/router";
declare var Auth0Lock: any;
#Injectable()
export class AuthService {
constructor(private router: Router) {}
lock = new Auth0Lock('KEY','URL');
login() {
this.lock.show((error: string, profile: Object, id_token: string) => {
if (error) {
console.log(error);
return false;
}
localStorage.setItem('profile', JSON.stringify(profile));
localStorage.setItem('id_token', id_token);
this.router.navigate(['Home']);
});
}
logout() {
localStorage.removeItem('profile');
localStorage.removeItem('id_token');
}
}
I tried annotating the AppComponent with #CanActivate as follows
but that doesn't seems to be working as the AppComponent is loaded any how.
#CanActivate(() => LoginComponent.loggedIn())
export class AppComponent {
}
Any ideas how to prevent the appComponent from loading without authnetication ?
You could implement your own RouterOutlet which overrides the acitvate method to check, if the person is allowed to navigate to that route.
import {Directive, DynamicComponentLoader, ElementRef} from "angular2/core";
import {AuthService} from '../../services/AuthService'
import {Router, RouterOutlet, ComponentInstruction} from "angular2/router";
#Directive({
selector: 'auth-router-outlet'
})
export class AuthRouterOutlet extends RouterOutlet {
private _protectedRoutes = {
'app/home': true,
'app/dashboard': true,
'app/about': true
};
constructor(_elementRef: ElementRef, _loader: DynamicComponentLoader, private _router: Router, nameAttr: string, private _authService: AuthService) {
super(_elementRef, _loader, _router, nameAttr);
}
activate(nextInstruction: ComponentInstruction): Promise<any> {
if (this._protectedRoutes[nextInstruction.urlPath]) {
if (!this._authService.loggedIn()) {
this._router.navigate(['Login']);
}
}
return super.activate(nextInstruction);
}
}
In your AppComponent just replace the <router-outlet></router-outlet> with <auth-router-outlet></auth-router-outlet>.
For the redirect in your RouteConfig use two asterisks like this:
#RouteConfig([
{path: 'app/home', component: HomeComponent, as: 'Home'},
{path: 'app/dashboard', component: DashboardComponent, as: 'Dashboard'},
{path: 'app/about', component: AboutComponent, as: 'About'},
{path: 'app/login', component: LoginComponent, as: 'Login'},
{path: 'app/**', redirectTo: ['Login']} // two asterisks here
])