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.
Related
I have a problem. I don't know how to send object from one component to another.
In first component cinema.component.html I have following function call:
<a title="Reserve" (click)="openReservationPage(repertoire)">Reserve</a>
In cinema.component.ts file, for that .html I have something like:
openReservationPage(repertoire: UpcomingRepertoire) {
this.router.navigate(['/reserve', {repertoire: JSON.stringify(repertoire)}]);
}
My app.routes.ts file contains appropriate routing:
{ path: 'reserve', component: ReserveFormComponent }
How can I use this repertoire object in another page reserve-form.component.ts and reserve-form.component.html ?
As an answer for the question in the title, i would said create a service to pass data between components.
Since its a router implementation you can pass the repertoire as a route parameter.
Follow these steps:
1)Modify the route in app.routes.ts to take a param
{ path: 'reserve/:repertoire', component: ReserveFormComponent }
2)In cinema.component.ts pass the repertoire as param
this.router.navigate(['/reserve',JSON.stringify(repertoire)]);
3)Extract the param in reserve-form.component.ts
First of all you need to import
import {ActivatedRoute } from "#angular/router";
Technique 1
repertoire:any;
constructor(private activatedRoute: ActivatedRoute) {
this.repertoire = JSON.parse(activatedRoute.snapshot.params["repertoire"]);
}
Technique 2
import { Subscription } from "rxjs/Rx";
private subscription: Subscription;
repertoire:any;
constructor(private activatedRoute: ActivatedRoute) {
this.subscription = activatedRoute.params.subscribe(
(param: any) => this.repertoire = JSON.parse(param['repertoire'])
);
}
ngOnDestroy() { // here we unsubscribe to the observable
this.subscription.unsubscribe();
}
Further Explanation :
Technique 1 is adopted when you are sure that the param will be passed every time you navigate to the component.
Technique 2 is a subscription to the observable once there a param published but don't forget to unsubscribe in the ngOnDestroy() component's life cycle method to prevent memory leak.
It is more preferable because some times there a scenario that a param is passed to a component after it was created where the snapshot method wouldn't capture and it more flexible with different scenario than the basic one in technique 1.
The link below explains how you can do this. I've recently used this to create a messaging service. The example below, shows the code for a simple messaging service. It allows you to pass a number between components, just change the to I guess. You can also write out to local storage, but It seems services are more popular. Once you've got your head around them, they're easy to re-use.
Hope this helps
Sharing Data Between Angular Components - Four Methods
Message Service (PmMessageService)
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
#Injectable()
export class PmMessageService
{
private pillMenuIndexBS = new BehaviorSubject <number> (null);
pillMenuIndex = this.pillMenuIndexBS.asObservable();
constructor() {}
setPillMenuIndex(index : number)
{
this.pillMenuIndexBS.next(index);
}
}
Component consuming message service, setting a value
import { Component, OnInit } from '#angular/core';
import { PmMessageService } from '../pm-message-service/pm-message.service'
import { BrowserModule } from '#angular/platform-browser';
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
#Component({
selector: 'app-pm-configure',
templateUrl: './pm-configure.component.html',
styleUrls: ['./pm-configure.component.css']
})
export class PmConfigureComponent implements OnInit
{
constructor (private messageService : PmMessageService) {}
ngOnInit()
{
this.messageService.setPillMenuIndex(1);
}
}
Component consuming and subscribing.
import { Component, OnInit } from '#angular/core';
import { PmMessageService } from '../pm-message-service/pm-message.service'
import { BrowserModule } from '#angular/platform-browser';
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
#Component({
selector: 'pm-bs-navbar',
templateUrl: './pm-bs-navbar.component.html',
styleUrls: ['./pm-bs-navbar.component.css']
})
export class PmBsNavbarComponent implements OnInit
{
tabActiveNumber;
constructor (private messageService : PmMessageService) {}
ngOnInit()
{
this.messageService.pillMenuIndex.subscribe(index => this.tabActiveNumber = index)
}
}
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 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()"
I'm learning Ionic 2 by building a simple app, but I've ran into a problem I can't solve.
The app has a ion-nav for the login page, after logging in it goes into a tabs navigator. So the app nav would be something like:
app<Nav> {
LoginPage,
restrictedTabs<Nav> {
Page1,
...
}
}
My problem is I don't know how to access appNav while I'm inside Page1, so that I can, for example, logout the user and block him from "restrictedTabs".
I've tried as the docs say with #ViewChild
import {Component, ViewChild} from '#angular/core';
import {NavController} from 'ionic-angular';
#Component({
templateUrl: 'page1url...'
})
export class ProfilePage {
#ViewChild('appNav') appNav : NavController
constructor(private _nav: NavController) {
}
pushNewPlace() {
console.log(this._nav.rootNav);
console.log(this._nav.parent);
}
ngAfterViewInit() {
console.log(this.appNav);
}
}
But appNav is always undefined, as is rootNav (which I've seen in some tutorial...). If I try #ViewChild('appNav') on LoginPage controller it works good
Because your navcontroller is local, you need to get access to the rootNav.
that is done thanks to the appController.
Tabs are creating a view inside the 'root' view.
In the page loaded inside one of the tabs :
First, import Nav from ionic-angular, same place as navController
import { App, NavController } from 'ionic-angular';
Be sure to have your loginPage also
import { LoginPage } from 'pages/login/login';
then provide it in your constructor :
constructor(public navCtrl: NavController, public appCtrl: App)
now you can acces the rootnav:
this.appCtrl.getRootNav().setRoot(myLoginPage);
I built a service that called lang.service.ts. What it does is simply a key: value mechanism. Whenever I need it to my component, I import it and declare it in the constructor and then I use it as {{lang('key').text}}. so far, so good.
The thing is that I've noticed that I'm gonna load it for each component, like for view-header.component.ts, view-footer.components.ts and a lot of other components. I never used Angular 1, but IIRC, I could do there something like rootScope.lang(..) and it could've accomplish what I was looking for. Is there a way to do something like that in Angular 2?
If you register your service at your root componet, all child components will have access to the service.
On your root component...
import { Component } from '#angular/core';
import { YourService } from './my-servive.service.ts';
import { ChildComponent } from './child-component.component.ts';
#Component({
selector: 'root-component',
providers: [YourService],
directives: [ChildComponent],
template: `<child-component></child-component>`
})
export class RootComponent {}
On your child component...
import { Component } from '#angular/core';
import { YourService } from './my-servive.service.ts';
#Component({
selector: 'child-component'
})
export class ChildComponent {
contructor(private myService: YourService) {}
}
Hope this help you.