https://www.npmjs.com/package/#ngx-translate/core
https://www.npmjs.com/package/#ngx-translate/http-loader
I installed translate package from here and added ngx-translate module with its forRoot , translate service inside component ts (app & header) but it isn't working also
Header component
<header>
<nav class="navbar navbar-expand-lg navbar-light" id="header">
<div class="container">
<a class="navbar-brand" href="#">
<img src=".." alt="logo">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
<a [routerLink]="['home']" class="nav-link">Home</a>
</li>
<li class="nav-item dropdown" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
<a class="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
page 2
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" [routerLink]="['page']">page</a></li>
</ul>
</li>
<li class="nav-item" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
<a class="nav-link" [routerLink]="['features']">Features</a>
</li>
<li class="nav-item" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
<a class="nav-link reserve-btn" [routerLink]="['reserve']">Reserve</a>
</li>
</ul>
</div>
<button (click)="translate.use('en')">
En
</button>
<button (click)="translate.use('ar')">
Ar
</button>
</div>
</nav>
</header>
Header.component.ts
import { DOCUMENT } from '#angular/common';
import { Component, HostListener, Inject, OnInit } from '#angular/core';
import { TranslateService } from '#ngx-translate/core';
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
})
export class HeaderComponent implements OnInit {
// lang: string;
constructor(#Inject(DOCUMENT) private document: Document,public translate:TranslateService) {}
ngOnInit(): void {
// this.lang = localStorage.getItem('lang') || 'en';
}
}
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { GeneralPagesModule } from './general-pages/general-pages.module';
import { RentalPageModule } from './rental-page/rental-page.module';
import { SharedModule } from './shared/shared.module';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { TranslateModule, TranslateLoader } from '#ngx-translate/core';
import { TranslateHttpLoader } from '#ngx-translate/http-loader';
import { HttpClientModule, HttpClient, HTTP_INTERCEPTORS } from '#angular/common/http';
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, './assets/i18n/', '.json');
}
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
SharedModule,
GeneralPagesModule,
RentalPageModule,
BrowserAnimationsModule,
// TranslateModule,
HttpClientModule,
TranslateModule.forRoot({
defaultLanguage:'en',
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [HttpClient]
}
}),
],
providers: [
// { provide: HTTP_INTERCEPTORS, useClass: HttpInterceptorService, multi: true },
],
bootstrap: [AppComponent]
})
export class AppModule { }
export function createTranslateLoader(http:HttpClient){
return new TranslateHttpLoader(http,'./assets/i18n/','.json')
}
I also tried same steps in app.component.ts
import { Component, Inject } from '#angular/core';
import * as AOS from 'aos';
import { DOCUMENT } from '#angular/common';
import { TranslateService } from '#ngx-translate/core';
import { ActivatedRoute, NavigationEnd, Router } from '#angular/router';
import { filter} from 'rxjs/operators';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
ngOnInit(){
AOS.init({
duration: 1200,
});
}
// Inject document which is safe when used with server-side rendering
constructor(#Inject(DOCUMENT) private document: Document,public translate:TranslateService,
private router: Router, private route: ActivatedRoute) {
}
}
in home.compoent.html
{{"HOME" || translate}}
home.compoent.ts
import { Component, OnInit } from '#angular/core';
import { TranslateService } from '#ngx-translate/core';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor(public translate:TranslateService) { }
ngOnInit(): void {
}
}
The pipe syntax is {{ 'my-translation-key' | translate }} - you have double || in your template, please change and try again.
Alternatively you can inject the translate service and use myTanslation = this.translateService.instant('my-translation-key') if you need to set a variable in your controller.
I Face the same problem and nothing works i tried all the ways it's was issue of angular/core12.0.0. I waste 3 days in it. It was working fine in angular 11 but no one angular 12. So Create custom pipe. :)
import { Pipe, PipeTransform } from '#angular/core';
import { TranslatePipe } from "#ngx-translate/core";
#Pipe({
name: 'myTranslate',
pure: false
})
export class MyTranslate extends TranslatePipe implements PipeTransform {
transform(value: any, args?: any[]): any {
return super.transform(value, args)
}
}
{{ myvalue | myTranslate }
Related
I have created a product module as a featured module and shift all child routes of the featured module in the product module from 'app-routing.module.ts'. I haven't added lazy loading yet. But after separating product routes the child routes are not working. The routes are redirecting to the pagenotfound routes.
app-routing.module.ts
const routes:Routes=[
{path:'',redirectTo:'/home',pathMatch:'full'},
{path:'home',component:HomeComponent},
{path:'about',component:AboutComponent},
{path:'product',component:ProductComponent},
{path:'contact',component:ContactComponent},
{path:'buy product',component:ParentComponent},
{path:'view',component:ViewchildComponent},
{path:"**", component:PageNotFoundComponent}
];
#NgModule({
imports:[RouterModule.forRoot(routes,{ enableTracing: false })],
exports:[RouterModule]
})
app.component.html
<nav mat-tab-nav-bar ngClass = "tabs">
<a mat-tab-link routerLink="/home" routerLinkActive="active">Home</a>
<a mat-tab-link routerLink="/about" routerLinkActive="active-link">About US</a>
<a mat-tab-link routerLink="/product" routerLinkActive="active-link">Products</a>
<a mat-tab-link routerLink="/contact" routerLinkActive="active-link">Contact Us</a>
<a mat-tab-link routerLink="/buy product" routerLinkActive="active-link">Buy Product</a>
<a mat-tab-link routerLink="/view" routerLinkActive="active-link">View Child</a>
</nav>
<router-outlet></router-outlet>
product.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { LatopComponent } from './latop/latop.component';
import { MobileComponent } from './mobile/mobile.component';
import { ComputerComponent } from './computer/computer.component';
import { MachineComponent } from './machine/machine.component';
import {RouterModule, Routes} from '#angular/router';
import { ProductComponent } from './product.component';
import { MaterialModule } from '../material/material.module';
const proRoute:Routes=[ {path:'product',children:[
{path:'',component:ProductComponent},
{path:'laptop', component:LatopComponent},
{path:'mobile',component:MobileComponent},
{path:'computer',component:ComputerComponent},
{path:'wahing machine',component:MachineComponent}
]}]
#NgModule({
declarations: [
ProductComponent,
LatopComponent,
MobileComponent,
ComputerComponent,
MachineComponent
],
imports: [
CommonModule,
MaterialModule,
RouterModule.forChild(proRoute)
]
})
export class ProductModule { }
product.component.html
<a routerLink='/laptop' mat-raised-button color="primary">Know Laptop</a>
<a routerLink='/mobile' mat-raised-button color="primary">Know Mobile</a>
<a routerLink='/computer' mat-raised-button color="primary">Know Computer</a>
<a routerLink='/wahing machine' mat-raised-button color="primary">Know Washing Machine</a>
It looks like both your AppRoutingModule and your ProductModule are registering a product route. Remove the one from your AppRoutingModule and the route registration should work.
(Also make sure that your ProductModule is imported in your AppModule, remembering that you will have to remove it once you've set up lazy loading.)
I create a form using Angular ReactiveFormsModule but I got this error message when building the app
ERROR in src/app/security/login/login.component.html:11:13 - error NG8002: Can't bind to 'formGroup' since it isn't a known property of 'form'.
11 <form [formGroup]="loginForm" (ngSubmit)="loginProces()">
for LoginComponent.
I copied the same code in LogoutComponent (for testing) and no error in this component.The two components are in same module -security.
login.component.html:
<div class="wrapper fadeInDown">
<div id="formContent">
<!-- Tabs Titles -->
<!-- Icon -->
<div class="fadeIn first">
<img src="" id="icon" alt="User Icon" />
</div>
<!-- Login Form -->
<form [formGroup]="loginForm" (ngSubmit)="loginProces()">
<input type="text" id="login" class="fadeIn second" name="login" formControlName="username" placeholder="login">
<input type="text" id="password" class="fadeIn third" name="login" formControlName="password" placeholder="password">
<input type="submit" class="fadeIn fourth" value="Log In">
</form>
<!-- Remind Passowrd -->
<div id="formFooter">
<a class="underlineHover" href="#">Forgot Password?</a>
</div>
</div>
</div>
Login.component.ts
import { Component, OnInit } from '#angular/core';
import { FormControl, FormGroup, Validators } from '#angular/forms';
import { LoginService } from '../services/login.service';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
loginForm:FormGroup;
constructor(private authService: LoginService) { }
ngOnInit(): void {
this.initForm();
}
initForm(){
this.loginForm = new FormGroup({
username: new FormControl("",[Validators.required]),
password : new FormControl("",[Validators.required])
});
}
loginProces(){
if(this.loginForm.valid){
this.authService.login(this.loginForm.value).subscribe(result=>{
if(result.success){
console.log(result);
alert(result.message);
}else{
alert(result.message);
}
})
}
}
}
Security.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { LoginComponent } from './login/login.component';
import { LogoutComponent } from './logout/logout.component';
import { RegisterComponent } from './register/register.component';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
#NgModule({
declarations: [
LoginComponent,
LogoutComponent,
RegisterComponent
],
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
],
exports:[
]
})
export class SecurityModule { }
What am I doing wrong?
Routing.module
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { LoginComponent } from './security/login/login.component';
const routes: Routes = [
{path:'login', component : LoginComponent }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
It is possible that the old bundle is still being served. The changes has to be included in the bundle which is being served. Restart the server and check if this problem persists.
ng serve
iam using ng-bootstrap to generate a popup modal, for example the first demo here https://ng-bootstrap.github.io/#/components/modal/examples, the problem here is,
when iam importing the FormsModule and ReactiveFormsModule in src/app/modal-basic.module.ts so the code inide it become like this
import { NgModule } from '#angular/core';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { BrowserModule } from '#angular/platform-browser';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { NgbdModalBasic } from './modal-basic';
#NgModule({ imports: [BrowserModule, NgbModule, FormsModule,ReactiveFormsModule],
declarations: [NgbdModalBasic],
exports:[NgbdModalBasic], bootstrap: [NgbdModalBasic]
})
export class NgbdModalBasicModule {}
and declaring a FormGroup in src/app/modal-basic so the code inside it become
import {Component} from '#angular/core';
import {FormGroup} from '#angular/forms';
import {NgbModal, ModalDismissReasons} from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'ngbd-modal-basic',
templateUrl: './modal-basic.html'
})
export class NgbdModalBasic {
closeResult = '';
exampleFormName:FormGroup;
constructor(private modalService: NgbModal) {}
open(content) {
this.modalService.open(content, {ariaLabelledBy: 'modal-basic-title'}).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}
}
and in src/app/modal-basic.html when iam adding [formGroup]="exampleFormName" in the form tag or add formContrtrolName="elementName" to a control element, so the code become like that
<ng-template #content let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Profile update</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form [formGroup]="exampleFormName">
<div class="form-group">
<label for="dateOfBirth">Date of birth</label>
<div class="input-group">
<input id="dateOfBirth" class="form-control" placeholder="yyyy-mm-dd" name="dp" ngbDatepicker #dp="ngbDatepicker" formControlName="dateOfBirth">
<div class="input-group-append">
<button class="btn btn-outline-secondary calendar" (click)="dp.toggle()" type="button"></button>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="modal.close('Save click')">Save</button>
</div>
</ng-template>
<button class="btn btn-lg btn-outline-primary" (click)="open(content)">Launch demo modal</button>
<hr>
<pre>{{ closeResult }}</pre>
i end up with a modal that doesn't popup but it appear after the last element in the page even though it was popup before adding
[formGroup]="exampleFormName" and formControlName="dateOfBirth"
i want to know where is the problem so please try the code form ng-bootstrap it self without my modifications then copy code from her and past it in stackblitz to se the problem.
thanks in advance.
You need use the FormControl for those inputs:
https://stackblitz.com/edit/angular-naoht3?file=src%2Fapp%2Fmodal-basic.ts
import { Component } from "#angular/core";
import {FormGroup, FormControl} from "#angular/forms"
import { NgbModal, ModalDismissReasons } from "#ng-bootstrap/ng-bootstrap";
#Component({
selector: "ngbd-modal-basic",
templateUrl: "./modal-basic.html"
})
export class NgbdModalBasic {
closeResult = "";
exampleFormName = new FormGroup({
name: new FormControl(),
dateOfBirth: new FormControl()
});
constructor(private modalService: NgbModal) {}
open(content) {
this.modalService
.open(content, { ariaLabelledBy: "modal-basic-title" })
.result.then(
result => {
this.closeResult = `Closed with: ${result}`;
},
reason => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
}
);
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return "by pressing ESC";
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return "by clicking on a backdrop";
} else {
return `with: ${reason}`;
}
}
}
I have a property in my AuthService wich tell you if you are log in or not.
export class AuthService {
token: string;
isLogIn = new Subject<boolean>();
When I login correctly I set the isLogIn to true in the other hand when I click logout I set the property to false. I have this logic in my AppComponent(the first component been loaded).
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in.
this.authService.user = new User(user.displayName, user.email, user.photoURL, user.uid);
console.log(user);
this.isLoading = false;
this.authService.isLogIn.next(true);
} else {
// No user is signed in.
console.error('no user is login');
this.authService.isLogIn.next(false);
}
});
In my HeaderComponent I have:
export class HeaderComponent implements OnInit {
isActivated = false;
constructor(private authService: AuthService) { }
ngOnInit() {
this.authService.isLogIn.asObservable().subscribe(
(data: boolean) => {
this.isActivated = data;
}
);
// this.isActivated = this.authService.isLogin();
}
}
the template:
<ng-template [ngIf]="!isActivated">
<a class="nav-item nav-link text-white anchor-hover"
routerLink="/login"
routerLinkActive="active font-weight-bold">
<i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Ingresar
</a>
</ng-template>
<ng-template [ngIf]="isActivated">
<!--DROPDOWN PROFILE-->
<div class="btn-group" role="group" *ngIf="authService.user">
<button id="btnGroupDrop1" type="button" class="btn btn-light dropdown-toggle pointer" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{{authService.user.displayName}}
</button>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
<a class="dropdown-item" href="#">Dropdown link</a>
<a class="dropdown-item" href="#">Dropdown link</a>
</div>
</div>
<a class="nav-item nav-link text-white anchor-hover"
routerLink="/dashboard"
routerLinkActive="active font-weight-bold">
<i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Dashboard
</a>
</ng-template>
What I'm approching here is that when the user is log in I show him a dashboard button and hide the login button but this is only seen if you refresh the page or chage the current route. I don't want to change the route or refresh the page to see differents UI components depending if you are log in or not.
Now I let you the entire files:
AppRouting Module:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import {HomeComponent} from './shared/home/home.component';
import {LoginComponent} from './public/login/login.component';
import {DashboardComponent} from './auth/dashboard/dashboard.component';
const routes: Routes = [
{path: '', component: HomeComponent},
{path: 'login', component: LoginComponent},
{path: 'dashboard', component: DashboardComponent}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule{}
AppComponent.ts
import {Component, OnInit} from '#angular/core';
import * as firebase from 'firebase';
import {AuthService} from './public/services/auth.service';
import {User} from "./auth/models/user.model";
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
isLoading = true;
constructor(private authService: AuthService) {}
ngOnInit() {
// this.authService.isLogIn.next(localStorage.length > 0);
firebase.auth().onIdTokenChanged(
(data) => {
console.log('TOKEN HAS CHANGED', data);
if(data) {
data.getIdToken().then(
(tk) => {
this.authService.token = tk;
}
);
} else {
console.log('You don\'t have a token yet, please login...');
// TODO this means that the user is new or have logout.
}
}
);
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in.
this.authService.user = new User(user.displayName, user.email, user.photoURL, user.uid);
console.log(user);
this.isLoading = false;
this.authService.isLogIn.next(true);
} else {
// No user is signed in.
console.error('no user is login');
this.authService.isLogIn.next(false);
}
});
// check localstorage, so we can see if there is a logged user
if (this.authService.getLocalUserInfo()) {
this.authService.isLogIn.next(true);
} else {
this.authService.isLogIn.next(false);
}
}
}
AppComponent Template:
<div>
<app-header></app-header>
</div>
<div>
<router-outlet></router-outlet>
</div>
AppHeader.ts
import { Component, OnInit } from '#angular/core';
import {AuthService} from '../../public/services/auth.service';
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
isActivated = false;
constructor(private authService: AuthService) { }
ngOnInit() {
this.authService.isLogIn.asObservable().subscribe(
(data: boolean) => {
this.isActivated = data;
}
);
// this.isActivated = this.authService.isLogin();
}
}
AppHeader Template
<nav class="navbar navbar-expand-lg navbar-dark bg-custom-nav px-5">
<a class="navbar-brand" routerLink="/">MovieApp</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="container-fluid">
<div class="collapse navbar-collapse d-lg-flex justify-content-lg-between row" id="navbarNavAltMarkup">
<div class="navbar-nav px-sm-4 px-lg-0">
<a class="nav-item nav-link text-white"
routerLink="/"
routerLinkActive="active font-weight-bold"
[routerLinkActiveOptions]="{exact: true}">Inicio</a>
</div>
<div class="col-lg-8">
<app-search-bar></app-search-bar>
</div>
<div class="row">
<ng-template [ngIf]="!isActivated">
<a class="nav-item nav-link text-white anchor-hover"
routerLink="/login"
routerLinkActive="active font-weight-bold">
<i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Ingresar
</a>
</ng-template>
<ng-template [ngIf]="isActivated">
<!--DROPDOWN PROFILE-->
<div class="btn-group" role="group" *ngIf="authService.user">
<button id="btnGroupDrop1" type="button" class="btn btn-light dropdown-toggle pointer" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{{authService.user.displayName}}
</button>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
<a class="dropdown-item" href="#">Dropdown link</a>
<a class="dropdown-item" href="#">Dropdown link</a>
</div>
</div>
<a class="nav-item nav-link text-white anchor-hover"
routerLink="/dashboard"
routerLinkActive="active font-weight-bold">
<i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Dashboard
</a>
</ng-template>
</div>
</div>
</div>
</nav>
AuthService.ts
import * as firebase from 'firebase';
import {Router} from '#angular/router';
import { Injectable } from "#angular/core";
import {Subject} from "rxjs/Subject";
import {User} from "../../auth/models/user.model";
#Injectable()
export class AuthService {
token: string;
isLogIn = new Subject<boolean>();
user: User;
constructor(private router: Router){}
signinWithFacebook() {
const provider = new firebase.auth.FacebookAuthProvider();
provider.addScope('user_location');
return firebase.auth().signInWithPopup(provider)
.then(
(res) => {
console.log(res);
this.getTokenId();
localStorage.setItem('userInfo', JSON.stringify(firebase.auth().currentUser.providerData[0]));
const userInfo = firebase.auth().currentUser.providerData[0];
this.user = new User(userInfo.displayName, userInfo.email, userInfo.photoURL, userInfo.uid);
this.isLogIn.next(true);
this.router.navigate(['/dashboard']);
}
);
}
getTokenId() {
firebase.auth().currentUser.getIdToken()
.then(
(tk) => {
return this.token = tk;
}
);
}
logout() {
return firebase.auth().signOut();
// handle in component
}
getLocalUserInfo(): boolean {
if(localStorage.getItem('userInfo')) {
const transformStoredUser = JSON.parse(localStorage.getItem('userInfo'));
this.user = new User(transformStoredUser.displayName, transformStoredUser.email, transformStoredUser.photoURL, transformStoredUser.uid);
return true;
} else {
return false;
}
}
isLogin():boolean {
if (localStorage.getItem('userInfo')) {
return true;
}
return false;
}
}
You can find the full project at: https://github.com/lucasdavidferrero/movieApp
One more thing, I've used the async pipe but the template doesn't reflect the chages. In the github project you'll find that I'm using async in the template but still the same bug. I hope someone could help me.
I'm going to try to help/answer, mind you there is a lot of code to sift through, so I may have missed something obvious. Anyway to hopefully neaten up your code and point you to the right direction you may want to look into the AsyncPipe.
I want to first modify your AuthService to get inline with some better practices, by first changing isLogIn = new Subject<boolean>(); to private _isLogIn = new Subject<boolean>();. We don't want to share the Subject to other components that will modify it, so everywhere in our AuthService you'll just need to add the underscore... Finally to export our Subject to be used we can add a get function like this:
get isLogIn(): Observable<boolean> {
return this._isLogIn.asObservable();
}
And now we don't need to chain the asObservable() to where ever we use it.
Also we want to move where you watch for changes in your user state from the AppComponent to your AuthService. Then you can instantiate the service in the constructor of your AppModule so your service will start to watch for changes in the auth state as soon as your app starts up.
You may also run into an issue where the resolve of the auth state may be falling out of zone, so while this may not be necessary you can/should import NgZone from core and pass it into your constructor of your AuthService constructor(private router: Router, private _zone: NgZone) { } so when you update the value of the auth state you can wrap it in this function:
this._zone.run(() => {
// your code here
}
Now if I was to write your header.component.ts I would have done something like this:
export class HeaderComponent implements OnInit {
constructor(private authService: AuthService) { }
ngOnInit() {}
get isActivated(): Observable<boolean> {
return this.authService.isLogIn;
}
}
So here I am just passing the observable straight to our template with a get function. So in the template I would implement the AsyncPipe like so:
<div *ngIf="!(isActivated | async) else user">
<a class="nav-item nav-link text-white anchor-hover" routerLink="/login"
routerLinkActive="active font-weight-bold">
<i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Ingresar
</a>
</div>
<ng-template #user>
<!--DROPDOWN PROFILE-->
<div class="btn-group" role="group" *ngIf="authService.user">
<button id="btnGroupDrop1" type="button" class="btn btn-light dropdown-toggle pointer" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{{authService.user.displayName}}
</button>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
<a class="dropdown-item" href="#">Dropdown link</a>
<a class="dropdown-item" href="#">Dropdown link</a>
</div>
</div>
<a class="nav-item nav-link text-white anchor-hover"
routerLink="/dashboard"
routerLinkActive="active font-weight-bold">
<i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Dashboard
</a>
</ng-template>
The AsyncPipe will automatically subscribe and unsubscribe to your Observable and handle the refresh/zone updates.
Now I gave some overview/basic changes I would do to make sure the code behaves as expected. I invite you to try this and see if your *ngIfs work more "neatly." However you may also want to look up if else in Angular... => https://stackoverflow.com/a/43006589/5076023
I have a angular2 component:
import {Component} from '#angular/core';
#Component({
selector: 'sidenav',
templateUrl: './sidenav.html',
styleUrls: ['./sidenav.scss'],
})
export class SidenavComponent {
constructor() {
}
}
I want to include it in another component, which works fine except that the links don't work:
<li><a routerLink="/portfolio">Portfolio</a></li>
I include the component simply with the tag
<sidebar> </sidebar>
what is the missing part. I included the router but it didn't help.
I use the generated jhipster app and want to add a sidenav only for authorized Users. There are many modules and routes defined including each other, but I just don't find the right way.
I include the component simply with the tag
<sidebar> </sidebar>
Isn't it supposed to be <sidenav> </sidenav>?
Maybe u r not using RouterModule correctly?
RouterModule.forRoot(<urRouteDataStructure>)
this is the setting in the imports-array.
I am sharing my code below for reference:-
(I am using bootstrap 3.x)
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
import { ServerComponent } from './server/server.component';
...
...
import {Routes, RouterModule} from '#angular/router';
const appRoutes: Routes = [
{ path:'server',
component: ServerComponent
}
];
#NgModule({
declarations: [
AppComponent,
ServerComponent,
BasicHighlightDirective,
BetterHighlightDirective,
UnlessDirective
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(appRoutes)
],
providers: [LoggingService, AccountsService],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<div class="container">
<div class="row">
<div class="col-xs-12">
<ul class="nav nav-tabs">
<!-- <li role="presentation"> Server Comp </li> -->
<li role="presentation"><a routerLink="/server"> Server Comp </a> </li>
<li role="presentation"><a routerLink="/"> Home Comp</a></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<router-outlet></router-outlet>
</div>
</div>
</div>
Heres my output screenshot: