How to get value from link in angular - javascript

How can I get a value from link in angular 4, I have made *ngIf and I want it to show div based on the value of the link
<div *ngIf="get the value from the current href">

<div *ngIf="isHomePage()>
and in TS,
isHomePage(): boolean {
return this.router.url == 'yourcheckurl';
}

import { Router } from '#angular/router';
add router in constructor and method in class
constructor(router: Router) {
}
getUrl() {
return this.router.url;
}
No change html code to
<div *ngIf="getUrl()">

you have to import router in the component
import { Router, ActivatedRoute } from '#angular/router';
if you dont have #angular/router you have to run "npm install #angular/router"
now inject router in your component like
constructor(private route: ActivatedRoute, private router: Router) { }
now you can write a method which returns true for your URL
return this.router.url === 'your URL'
then you can call that method inside *ngIf="isYourPage()"

Related

Angular 2 Routerlink *ngIf with Param

I have the following routerlink which contains a param:
http://localhost:4200/item/1
How would I go about doing an *ngIf with a param....
I tried the following
<div *ngIf="router.url === '/item/:item_id'">
</div>
The component which I'm running this *ngIf is a header component which isn't connect to the itemComponent
Have you tried using ActivatedRoute.
Import into your component
import { ActivatedRoute } from '#angular/router';
then get your url value as following..
constructor(private route: ActivatedRoute) {
this.route.params.subscribe(params => {
this.item_id = +params['item_id'];
});
after this you implement your logic for DOM view.

Angular4: Reload data on refresh in app-wide singleton service

Working on a small angular project with a few components that represent the views, the app has a home component which contains a list of items which when clicked load the views in the other(appropriate) components. The project has a service that provides data to all the components, this service loads the shared data from an API when the home component's ngOnInit() {} method is called after which the data is available to every other component in the app.
Now, my problem is when a user enters the full url path to any other component apart from the home component(usually due to hitting refresh while on this component), the data in the service is lost and the component has nothing to display. Is there a way to make the home component always load first even when a direct path to the component is entered into the url? Should I just always check in every component if data has been loaded and load if not? Thank you
Here is the source for the Home Component.
import { Component, OnInit } from '#angular/core';
import { ServiceCodeService } from './service-code.service';
import { ActivatedRoute, Router } from '#angular/router';
#Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent implements OnInit {
private specialityList: string[];
private route: ActivatedRoute;
private router: Router;
private svpList: string[];
constructor(private serviceCodeService: ServiceCodeService, route: ActivatedRoute, router: Router) {
this.route = route;
this.router = router;
}
ngOnInit() {
this.serviceCodeService.updateServiceCodesFromAPI().subscribe(
servCodes => {
this.specialityList = this.serviceCodeService.getAllSpecialities();
}
);
}
specialitySelected(item: any) {
this.router.navigate(['../speciality/'.concat(item)], {relativeTo: this.route});
}
svpSelected(item: any) {
this.router.navigate(['../svp/'.concat(item)], {relativeTo: this.route});
You could add a <router-outlet> to your home component, and then make the other views (/speciality etc...) children routes of the home route.
This would ensure that the home route always loads first
this.serviceCodeService.updateServiceCodesFromAPI().subscribe(
servCodes => {
if(servCodes) {
console.log(servCodes);
this.specialityList = this.serviceCodeService.getAllSpecialities();
}
}
);
You can do above mentioned code in all the components.

How to redirect to a route on ngOnit?

I am trying to redirect to a route when user directly paste the url.
I want to direct the user to /en/sell page on hitting the url
http://localhost:3000/en/sell/confirmation
here is my code,
ngOnInit() {
this.storedListing = this.sellerFlow.getSellerFlowObject();
if (this.storedListing === null) {
this.router.navigate(['./']);
}
}
i can see this.router getting executed but the application does not have any change. what is the issue?
You have to use ../ if you want to go from /en/sell/confirmation to /en/sell/:
this.router.navigate(['../']);
See the documentation.
You could instead redirect from your routing:
{
path: 'en/sell/confirmation',
redirectTo: 'en/sell',
pathMatch: 'full'
},
import {OnInit} from '#angular/core';
import {Router} from '#angular/router';
export class AddDisplay {
constructor(private router: Router){}
ngOnInit() {
this.router.navigate(['./SomewhereElse']);
}
}
You have to specify the relativeTo param, as below:
import { ActivatedRoute, Router } from '#angular/router';
constructor(private route: ActivatedRoute, private router: Router) { }
ngOnInit() {
this.storedListing = this.sellerFlow.getSellerFlowObject();
if (this.storedListing === null) {
this.router.navigate(['../'], { relativeTo: this.route });
}
}

Struggling through AuthGuard in Angular

Tried to follow AuthGuard example available here:
http://www.sparkbit.pl/angular-2-route-guards-real-life-example/
Unfortunately, while trying to implement the ActivationGuard.ts file, I'm receiving few errors.
ERROR in C:/Users/app/src/app/ActivationGuard.ts (6,24): Cannot find name 'ActivatedRouteSna
pshot'.)
C:/Users/app/src/app/ActivationGuard.ts (6,55): Cannot find name 'RouterStateSnapshot'.)
C:/Users/app/src/app/ActivationGuard.ts (13,62): Cannot find name 'CurrentUserService'.)
C:/Users/app/src/app/ActivationGuard.ts (15,31): Cannot find name 'ActivatedRouteSnapshot'.)
C:/Users/app/src/app/ActivationGuard.ts (15,62): Cannot find name 'RouterStateSnapshot'.)
Which basically means that the elements inside the CanActivate interface and inside constructors are not defined.
routing file:
import { WorksheetAccessGuard } from "./ActivationGuard";
const appRoutes: Routes = [
{ path: '', component: LoginComponent },
{ path: 'app', component: AppComponent, canActivate: [WorksheetAccessGuard] },
{ path: '**', redirectTo: '' }
];
My question: From where could I get these missing elements?
Provided image of my IDE: (the red words are the missing ones)
EDIT
I have made a custom service. I'm not sure if its fine or not:
import {Injectable} from '#angular/core';
import {Http} from '#angular/http';
#Injectable()
export class UserAuthenticationService {
isUserAuthenticated: boolean = false;
username: string;
constructor(private http: Http) {
}
authentication() {
this.http.get(`http://localhost/api/auth/isLogged/${this.username}`)
.subscribe(res => {
this.isUserAuthenticated = res.json();
},
err => {
console.error('An error occured.' + err);
});
}
}
Now I'm receiving some error inside the AuthGuard file:
ERROR PIC
**My main goal is checking with every component change (when user navigates over the page) if he is logged or not. If not - return him to the login page.
EDIT2
Can I just post all logic from the service in the AuthGuard file? It will look like:
import {Injectable} from '#angular/core';
import {Router, RouterStateSnapshot, ActivatedRouteSnapshot} from '#angular/router';
import {Observable} from 'rxjs/Observable';
import {UserAuthenticationService} from './UserAuthenticationService';
import {Http} from '#angular/http';
interface CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean
}
#Injectable()
export class WorksheetAccessGuard implements CanActivate {
private static username: string;
isUserAuthenticated: boolean = false;
constructor(private router: Router, private userService: UserAuthenticationService, private http: Http) {
}
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
this.http.get(`http://localhost/api/auth/isLogged/${this.username}`)
.subscribe(res => {
this.isUserAuthenticated = res.json();
},
err => {
console.error('An error occured.' + err);
});
if (!this.isUserAuthenticated) {
this.router.navigate(['/']);
return false;
}
return true;
}
}
RouterStateSnapshot and ActivatedRouteSnapshot are imported from #angular/router, while the currentUser Service is supposed to be your own where you should store the authenticated state of your User (with a boolean for example).
You retrieve an instance of it through Dependency Injection in your guard's constructor like so :
import { CurrentUserService } from './path/to/your/service/file';
import { RouterStateSnapshot, ActivatedRouteSnapshot } from '#angular/router';
constructor(private userService: CurrentUserService)
{}
Your service needs to be provided in your module, (as well as your guard), and you need to have a property like this in your CurrentUserService :
CurrentUserService :
isAuthenticated: boolean = false;
That way, when you log in from your Login Component (I assume you have one), you can set the service property to true :
LoginComponent :
import { CurrentUserService } from './path/to/your/service/file';
constructor(private userService: CurrentUserService)
{}
login() {
... // Your existing code where you login on form submit or anything
this.userService.isAuthenticated = true;
}
EDIT :
Check out my example, it should fit for yours.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (!this.authService.isAuthenticated) {
// Deny navigation and redirect to login
this.router.navigate(['/path/to/login']);
return false;
}
// Allow navigation (be careful that the guard always resolve a value)
return true;
}

Angular make canActivateGuard asynchronous

I have a web application where there is a JWT token passed to the admin service. This JWT comes from the query URL as there is a redirect from another application. The constructor in the service checks for that URL and set the token value to it (if that params is there).
The problem I am facing is that the canActivateGuard fires too early. When this is called the observable to get the JWT in the service is not solved yet, so the JWT is always not there when the guard is being fired.
I have figure out that to make this work isLoggedIn() in the AdminService has to become an observable that listen to the changes in the URL, and the canActivate() in the guard has to subscribe to it, but can not make this works.
The below code is what I got so far
// Admin Service
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Rx';
import 'rxjs/Rx';
import {Router, ActivatedRoute, Params} from '#angular/router';
#Injectable()
export class AdminService {
token: string;
constructor(private activatedRoute: ActivatedRoute) {
activatedRoute.queryParams.subscribe(
(params) => {
console.log('queryParams', params);
if(localStorage.getItem('jwt')) {
this.token = localStorage.getItem('jwt');
}
else if(params['jwt']) {
localStorage.setItem('jwt', params['jwt']);
this.token = params['jwt'];
}
});
}
// Check that JWT is in local storage and valid
isLoggedin() {
return (localStorage.getItem('jwt') !== null && localStorage.getItem('jwt') !== 'undefined');
}
}
// Can Activate guard
// Note that this.authService.isLoggedIn() is called before the set JWT in the service is solved
#Injectable()
export class AuthGuard implements CanActivate {
constructor(
private authService: AdminService,
private router: Router
) {
}
canActivate() {
if (this.authService.isLoggedin()) {
console.log('all ok, proceed navigation to routed component')
return true;
}
else {
// start a new navigation to redirect to login page
this.router.navigate(['/unauthorized']);
return false;
}
}
}
using ActivatedRouteSnapshot and RouterStateSnapshot your problem will be get resolve, and you don't need to subscribe for JWT in your service.
Here is a sample of my code which i had used in my Angular2 application.
auth-guard.ts
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '#angular/router';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { AuthCookie } from '../shared/services/auth-cookies-handler';
#Injectable()
export default class AuthGuard implements CanActivate {
constructor(private router: Router, private _authCookie: AuthCookie) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
if (this._authCookie.getAuth()) {
return true;
}
else {
this.router.navigate(['/login']);
return false;
}
}
}
Hope this will help you.

Categories