injecting service into CanActivate method of router Guard - angularjs

before redirecting to page i am doing simple check using below service
import { Injectable,OnInit } from '#angular/core';
export class UserCheck {
private userState:boolean = false;
get isValid(): boolean{
return this.userState;
}
set isValid(usrstate){
this.userState = usrstate;
}
}
User check is service that set isValid to true or false in another service;
Assume that another service has set isValid to true, I am using providers to have sigle instance of UserCheck of usercheck service. But when guard actually get executed its not considering value that was set to true.
import { CanActivate,ActivatedRouteSnapshot,RouterStateSnapshot } from '#angular/router';
import { UserCheck } from './UserCheck' ;
import { Observable } from 'rxjs/Rx';
import { Injectable } from '#angular/core';
#Injectable()
export class UserDetailGuard implements CanActivate{
constructor (private usrstate:UserCheck){
console.log ("guard in action " + this.usrstate.isValid) }
canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot) : Observable<boolean> | boolean{
console.log ("guard executed.. " + this.usrstate.isValid)
return this.usrstate.isValid;
}
}
As soon as page load value of this.usrstate.isValid can be seen to true in console log guard in action true in constructor code (see image), but when i actually navigate to page it does not consider value of this.usrstate.isValid and assign default value which is false.
app.module.js
Removed unnecessary code..
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { FormsModule,ReactiveFormsModule } from '#angular/forms';
import { routing } from './app.rotes';
import { UserCheck } from './UserCheck';
import { LogMessage } from './LogMessage';
import { AccessDenied } from './AccessDenied';
import { UserDetailGuard } from './UserDetailGuard'
#NgModule({
imports: [ BrowserModule,FormsModule,ReactiveFormsModule,routing,],
declarations: [ AppComponent,AccessDenied ],
bootstrap: [ AppComponent],
providers: [UserCheck,LogMessage,UserDetailGuard]
})
export class AppModule { }

Related

How add Name to Route in Angular 13 as like Vue

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

How do I fix 'this.http.get is not a function' error?

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.

Angular 2 EXCEPTION: TypeError: Cannot read property 'next' of undefined

I am trying to update a variable from my service to component. when i try to subscribe to it in the component i am getting error. can anyone help me please.
import {Injectable, } from 'angular2/core';
import {Router} from 'angular2/router';
import {MasterComponent} from '././master/master.component';
import 'rxjs/Rx';
import { Observable } from "rxjs/Observable";
import { Subscription } from "rxjs/Subscription"
import {Subject} from "rxjs/Subject"
#Injectable()
export class ConnectService
{
showValues: string;
public showValuesChange: Subject<string> = new Subject<string>();
constructor() {
this.showValues="1";
}
recvNotify(m) {
buttonName = innervalue;
console.log("ELSEinnervalue",buttonName);
switch (buttonName) {
case "0x01010000":
console.log('showValue==1');
this.showValues = "1";
this.showValuesChange.next(this.showValues);
break;
case "0x01020000":
console.log('showValue==2');
this.showValues = "2";
this.showValuesChange.next(this.showValues);
$('#showValue').prop("value",2);
break;
default:
console.log('showValue==3');
this.showValues = "3";
this.showValuesChange.next(this.showValues);
break;
}
}
}
Component: Here i want to get the updated showValues from the service when ever there is a change in the value.
import {Component} from 'angular2/core';
import {ConnectService} from '../connect.service';
import {Router} from 'angular2/router';
import 'rxjs/Rx';
import {Observable} from 'rxjs/Observable';
import {Subscription} from 'rxjs/Subscription';
#Component({
selector: 'Master',
templateUrl: './app/master/master.component.html',
providers: [ConnectService]
})
export class MasterComponent {
//showValue: any;
public showValues: string;
//show: any;
constructor(
public connectService: ConnectService,
public _router: Router,
public _subscription: Subscription){
if(localStorage.getItem("clientStatus")=='connected'){
this.showValues = connectService.showValues;
this._subscription = connectService.showValuesChange.subscribe((value) => {
this.showValues=value;
console.log("import {Observable} from 'rxjs/Observable';",this.showValues);
});
this._router.navigate(['Master']);
} else {
this._router.navigate(['Home']);
}
}
ngOnDestroy() {
this._subscription.unsubscribe();
}
}

Making moment injectable in angular2

I would like to make moment to be injectable through out my app.
I just started learning ng2 and couldn't find this type of usage in the docs.
Here is what I have in my 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 * as moment from 'moment';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule
],
providers: [{provide: 'moment', useValue: moment}],
bootstrap: [AppComponent]
})
export class AppModule {
}
and here is the component:
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.sass']
})
export class AppComponent {
title = 'app works!';
constructor(private moment) {
this.title += this.moment;
}
}
there is this error:
Uncaught Error: Can't resolve all parameters for AppComponent:
How should this be done correctly?
UPDATED MODULE
const moment = new OpaqueToken('moment');
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule
],
providers: [{provide: moment, useValue: moment}],
bootstrap: [AppComponent]
})
export class AppModule {
}
UPDATED COMPONENT
import { Component } from '#angular/core';
import * as moment from 'moment';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.sass']
})
export class AppComponent {
title = 'app works!';
constructor(private moment: moment) {
this.title += this.moment()
}
}
There is an error on this line constructor(private moment: moment) which tells that: Cannot find name 'moment'.
Moment by itself is not an injectable for Angular2. However it can be wrapped inside one.
Plunker Demo
moment.service.ts
import { Injectable } from '#angular/core';
import * as m from 'moment';
#Injectable()
export class MomentService {
moment = m;
}
app.module.ts
import { MomentService } from './moment.service';
#NgModule({
providers: [MomentService]
...
app.component.ts
import { MomentService } from './moment.service';
export class AppComponent {
constructor(private ms: MomentService){
console.log('Moment:' + this.ms.moment("20111031", "YYYYMMDD").toString());
}
}
Not perfect, but works.
You need to use OpaqueToken which will allowed you to create a string based token. I'd just suggest you to change the name of moment to avoid thr collision with moment variable of library.
// You can place this is some file, so that you can export it.
export const Moment = new OpaqueToken('moment');
and then you could use
providers: [{provide: MomentStatic, useClass: moment}],
You can go through this article for more details
While using dependency include it in a Component constructor.
constructor(private moment: MomentStatic)
Moment doesn't have to be injected, it is a library that you can "just use". It's enough to import it in your typescript file now you can use moment's features.
If you are loading moment.js so it is available globally how about wrapping it with a service which you can then inject throughout your app?
import {Moment} from '../../node_modules/moment';
import { Injectable } from '#angular/core';
declare var moment: any;
#Injectable()
export class MomentService {
constructor() { }
get(): Moment {
return moment;
}
}
I this way you get the TS IntelliSense when you are coding (at least I do in VSCode) and you can handle mocking moment for testing easily too.
The best workaround that I have come to find is to create a wrapper service, but also expose some of the most common methods directly on the service itself using getters:
import { Injectable } from '#angular/core';
import * as moment from 'moment';
/**
* A wrapper for the moment library
*/
#Injectable()
export class MomentService {
/**
* Creates and returns a new moment object with the current date/time
*/
public moment() { return moment(); }
// expose moment properties directly on the service
public get utc() { return moment.utc; }
public get version() { return moment.version; }
public get unix() { return moment.unix; }
public get isMoment() { return moment.isMoment; }
public get isDate() { return moment.isDate; }
public get isDuration() { return moment.isDuration; }
public get now() { return moment.now; }
}
Not sure if this helps now but you need something similar (not tested) to the following to make it work in your service.
import { Inject } from '#angular/core';
constructor(#Inject(moment) private moment) {
this.title += this.moment()
}
The key bit is the #Inject

Ng2 <Component> is not a known element

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() { }
}

Resources