Angular/Angular2, Refresh Component From routerLink (NavBar) , If already in existing route - javascript

If i am on same route , and i click again from nav bar. It doesn't do anything .
How can I refresh my component from navbar itself. Is there any method in routerLink.
<li [routerLinkActive]="['active']"><a [routerLink]="['/campaigns']">Creative</a></li>
<li [routerLinkActive]="['active']"><a [routerLink]="['/market-survey']">Survey</a></li>
click again means, suppose you click on creative (in my example) corresponding route will activate and component is loaded . Then I again click on creative . I want that component should refresh

This can be fixed this by creating another component
refresh.component.ts
import { Component, OnInit } from '#angular/core';
import {Router, ActivatedRoute, Params} from '#angular/router';
#Component({
selector: 'app-refresh',
template: `
<p>
refresh Works!
</p>
`,
styles: []
})
export class RefreshComponent implements OnInit {
constructor(private activatedRoute:ActivatedRoute,private route:Router) { }
ngOnInit() {
this.activatedRoute
.queryParams
.subscribe(params => {
if(params.url){
this.route.navigate([params.url]);
}
});
}
}
app.routing
{path: 'refresh',component:RefreshComponent},
and my new naviation li is
<li [routerLinkActive]="['active']"><a [routerLink]="['/refresh']" [queryParams]="{url:'campaigns'}" skipLocationChange="true">My AMP Creative</a></li>

Related

How to get previous route on 404 Error page in angular?

I have some pages and when I change router link to some wrong url and it redirect me to 404 page. In this 404 Error page I have button that will redirect me to previous page. Now I have some problems that this redirect button when I click it redirects to that wrong url and again to 404.
I try to show by photo:
1)My route. write wrong url -> redirect to 404 page.
Now the problem is when I click button to redirect at the previous route "Home" it redirect me to this wrong route.
goBack() {
this._location.back();
}
You can use JS history API to achieve this.
This is a sample to match your use case
goBack() {
window.history.go(-2);
}
And this also keeps navigiation within the SPA scope (Page wouldn't refresh).
Side effect for this is that you need to make sure that the user follows a particular flow; in which he needs to be within a working page, then goes somewhere not found then get redirected to the 404 Page..
I would recommend a button that navigates to Home or Dashboard features instead.
You can achieve this by number of ways , however I think the most elegant way is to use power of Injectable services in Angular.
Here is my solution of this problem:
Create an Injectable service which will set a variable as soon as the current navigation end. The value of this variable can be used in any of the other components where ever we would need. Obviously one has to inject the service in the required component.
In my example, I have created RouterService:
import { Injectable } from '#angular/core';
import { Router, NavigationEnd } from '#angular/router';
#Injectable({ providedIn: 'root' })
export class RouterService {
private previousUrl: string = undefined;
private currentUrl: string = undefined;
constructor(public router : Router) {
this.currentUrl = this.router.url;
router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
this.previousUrl = this.currentUrl;
this.currentUrl = event.url;
};
});
}
public getPreviousUrl(){
return this.previousUrl;
}
}
To illustrate the navigation , I have created two components viz. home and not-found Components.
Below are the code snippets for both of these components :
a) home.component.ts :
import { Component, VERSION } from '#angular/core';
import { NavigationEnd, Router } from '#angular/router';
import { filter } from 'rxjs/operators';
import { RouterService } from '../../service/router.service';
#Component({
selector: 'not-home-app',
templateUrl: './home.component.html',
styleUrls: [ './home.component.scss' ]
})
export class HomeComponent {
name = 'Angular ' + VERSION.major;
constructor(private router: Router,private routerService: RouterService) {}
takeMeToNotFoundPage(){
this.router.navigate(['/notFound']);
}
}
b) not-found.component.ts:
import { Component, VERSION } from '#angular/core';
import { NavigationEnd, Router } from '#angular/router';
import { filter } from 'rxjs/operators';
import { RouterService } from '../../service/router.service';
#Component({
selector: 'not-found-app',
templateUrl: './not-found.component.html',
styleUrls: [ './not-found.component.scss' ]
})
export class NotFoundComponent {
previousUrl: string;
constructor(private router: Router, private routerService: RouterService) {
router.events
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe((event: NavigationEnd) => {
console.log('prev:', event.url);
this.previousUrl = event.url;
});
}
loadPreviousRoute(){
let previous = this.routerService.getPreviousUrl();
if(previous)
this.routerService.router.navigateByUrl(previous);
}
}
When the application will first load, I will route it to 'home' page. There I provided a button to navigate to not-found page.
As you see in the above code of home component , I am setting the previous url in the router service which I can use in next component ( in this example it is 'not-found' component'
c) below are the html code snippets for both home and not-found components :
Home.component.html :
<hello name="{{ name }}"></hello>
<p>
Start editing to see some magic happen :)
</p>
<button type="button" (click)="takeMeToNotFoundPage()">Not FOUND!</button>
not-found.component.html:
<p>
<span style="background-color: red">NOT FOUND!!</span>
</p>
<button type="button" (click)="loadPreviousRoute()">Go Back to Previous Route</button>
Hope this will help you to solve your problem. If it will , please provide your feedback and upvote it accordingly as it will help others in future too.

How do I pass data from one component to another (New Browser Tab) in angular?

I'm new to angular and I don't know how to pass data between two components using routers. This is my first component view,
when I press view report button I need to call another component with the first component data. This is my first component view report click button code.
<button type="button" (click)="onFuelViewReport()" class="btn btn-success ">
<b>view Report</b>
</button>
when clicking the button it calls onFuelViewReport() function in the first component and using this function it opens the second component view with a new browser window (tab). What I want is to pass data from the first component to the second component from here. Please help me to do this.
onFuelViewReport() {
this.router.navigate([]).then(result => {
window.open("/pages/view-report", "_blank");
});
}
If you want to share data from child component to parent component, you can use #Output event emitter or if your are trying to share data within unrelated components, you can use BehaviourSubject (This also works in case of parent to child component communication and vice versa).
Child to Parent: Sharing Data via Output() and EventEmitter
parent.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-parent',
template: `
Message: {{message}}
<app-child (messageEvent)="receiveMessage($event)"></app-child>
`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent {
constructor() { }
message:string;
receiveMessage($event) {
this.message = $event
}
}
child.component.ts
import { Component, Output, EventEmitter } from '#angular/core';
#Component({
selector: 'app-child',
template: `
<button (click)="sendMessage()">Send Message</button>
`,
styleUrls: ['./child.component.css']
})
export class ChildComponent {
message: string = "Hola Mundo!"
#Output() messageEvent = new EventEmitter<string>();
constructor() { }
sendMessage() {
this.messageEvent.emit(this.message)
}
}
Unrelated Components: Sharing Data with a Service
data.service.ts
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs';
#Injectable()
export class DataService {
private messageSource = new BehaviorSubject('default message');
currentMessage = this.messageSource.asObservable();
constructor() { }
changeMessage(message: string) {
this.messageSource.next(message)
}
}
parent.component.ts
import { Component, OnInit } from '#angular/core';
import { DataService } from "../data.service";
#Component({
selector: 'app-parent',
template: `
{{message}}
`,
styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
}
sibling.component.ts
import { Component, OnInit } from '#angular/core';
import { DataService } from "../data.service";
#Component({
selector: 'app-sibling',
template: `
{{message}}
<button (click)="newMessage()">New Message</button>
`,
styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
newMessage() {
this.data.changeMessage("Hello from Sibling")
}
}
The window.open looks absolutely awful. Use this.router.navigate(['/heroes']);.
So if I understand correctly you have a list of items and when you click on one of the items, the details page of that item should open?
Best practice is to allow the detail route to have a property to set. the Angular Routing & Navigation page is very complete. It shows that you should use :id - { path: 'hero/:id', component: HeroDetailComponent }. When you open the detail page, you get the id variable and then get the data for it.

Angular how to hide a global component when a specific route is opened? [duplicate]

This question already has answers here:
How to Update a Component without refreshing full page - Angular
(7 answers)
Closed 3 years ago.
I'm not sure whether this is possible or not in angular but I wanted to hide a global component when a specific route is opened.
Say for example I have the following:
app.component.html
<app-header></app-header>
<app-banner></app-banner> <!-- Global Component I want to hide -->
<div class="body-container">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
app-routing.module.ts
import {NgModule} from '#angular/core';
import {Route, RouterModule} from '#angular/router';
import { StudentListComponent } from './Components/StudentList/StudentList.component';
import { SchoolMottoComponent } from './Components/SchoolMotto/SchoolMotto.component';
const routes: Routes = [
{path: 'StudentList', component: StudentListComponent },
{path: 'SchoolMotto', component: SchoolMottoComponent }
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
export const routingComponents = [StudentListComponent, SchoolMottoComponent]
With this, its a given that when I want to view the StudentList Component, then the url by default becomes localhost4200:/StudentList and the same with SchoolMotto it becomes localhost4200:/SchoolMotto.
Within the StudentListComponent, is an ag-grid that displays list of students, and when you click one of those students the url becomes something like this: localhost4200:/StudentList/view/cf077d79-a62d-46e6-bd94-14e733a5939d and its another sub-component of SchoolList that displays the details of that particular student.
I wanted to hide the Global banner component when the url has something like that: localhost4200:/StudentList/view/cf077d79-a62d-46e6-bd94-14e733a5939d. Only when the user views the specific details of a student.
Something like this:
app.component.html
<app-header></app-header>
**<app-banner *ngIf="router != '/StudentList/view/'"></app-banner> <!-- Global Component I want to hide -->**
<div class="body-container">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
Is this doable or not? If it is, how?
You could use event emitter or subject to emit an event when you're in StudentList/view and use ngIf to hide the banner.
In your StudentList component.ts :
export class StudentList {
bannerSubject: Subject<any> = new Subject<any>();
ngOnInit() {
bannerSubject.next(true);
}
}
subscribe to this in your parent component and you can easily hide the banner.
You can acheieve that with the help of component interation using a service
You will use the help of Rxjs Observables here
You will emit an event when you reach the student view component, then recieve that event in app component then change the view condition
New Service:
import { Injectable } from '#angular/core';
import { Subject } from 'rxjs';
#Injectable()
export class RouteService {
private routeChangedSource = new Subject<string>();
// Observable string streams
routeChanged$ = this.routeChangedSource.asObservable();
// Service message commands
changeRoute(mission: string) {
this.routeChangedSource.next(mission);
}
}
Student View Component.
import { Component } from '#angular/core';
import { routeService } from './mission.service';
#Component({
})
export class MissionControlComponent implements ngOnInit{
constructor(private routeService: routeService) {}
ngOnInit() {
this.routeService.changeRoute(mission);
}
}
App Component:
import { Component, Input, OnDestroy } from '#angular/core';
import { RouteService } from './route.service';
import { Subscription } from 'rxjs';
export class AppComponent implements OnDestroy {
studentView = false;
constructor(private routeService: RouteService) {
this.subscription = routeService.routeChanged$.subscribe(
value => {
this.studentView = true;
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Now, your App Component can be:
<app-header></app-header>
<app-banner *ngIf="!studentView"></app-banner>
<div class="body-container">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
<app-header></app-header>
<app-banner *ngIf="myService.hideGlobalComp"></app-banner> <!-- Global Component I want to hide -->
<div class="body-container">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
in the ts file:
onCellClicked($event) { // place into your method there you want.
this.route.parent.url.subscribe(urlPath => {
this.url = urlPath[urlPath.length - 1].path;
});
if(this.url === 'StudentList/view') {
this.myService.hideGlobalComp = true;
}
}
}
In you ts file do like this.
add new variable router: string;
add in construction add this
constructor(private _router: Router){
this.router = _router.url;
}
Then in HTML use same code.
Let me know if this does not work.

On router link click event - angular2

Hey I have this component (this is my parent controller):
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
#Component({
templateUrl: 'user.component.html'
})
export class UserComponent implements OnInit {
isCompleted: Boolean = false;
constructor(private router: Router) {
this.router.events.subscribe((v) => {
this.isCompleted = true;
})
}
ngOnInit() {
}
}
UserComponent.isCompleted is a variable used by loading bar.
I have subscribed to router events and value of UserComponent.isCompleted will be changed when router done loading. I need to change UserComponent.isCompleted to false on router link click.
I know I can do it with click event like this:
<a class="item" [routerLink]="['/dashboard']" [routerLinkActive]="['active']" (click)="myFnc()">Dashboard</a>
But I looking for any other way to make it global.

Angular 2 redirect on click

How to create simple redirect on click on some button in Angular 2? Already tried:
import {Component, OnInit} from 'angular2/core';
import {Router, ROUTER_PROVIDERS} from 'angular2/router'
#Component({
selector: 'loginForm',
templateUrl: 'login.html',
providers: [ROUTER_PROVIDERS]
})
export class LoginComponent implements OnInit {
constructor(private router: Router) { }
ngOnInit() {
this.router.navigate(['./SomewhereElse']);
}
}
You could leverage the event support of Angular2:
import {Router} from '#angular/router';
#Component({
selector: 'loginForm',
template: `
<div (click)="redirect()">Redirect</div>
`,
providers: [ROUTER_PROVIDERS]
})
export class LoginComponent implements OnInit {
constructor(private router: Router) { }
redirect() {
this.router.navigate(['./SomewhereElse']);
}
}
I would make it more dynamic using method parameters
Import the angular router
import { Router } from '#angular/router';
Create a button with click event
<div (click)="redirect(my-page)">My page</div>
Create a method with a pagename parameter
redirect(pagename: string) {
this.router.navigate(['/'+pagename]);
}
When clicked the router should route to the correct page
I'd say use routerLink directive & placed that over a(anchor) tag
<a [routerLink]="['./SomewhereElse']">Redirect</a>
Also you need to remove ROUTER_PROVIDERS from providers & include it in bootstrap dependency and then add ROUTER_DIRECTIVES in directives option of component to use routerLink directive on HTML. Make sure RouterModule with its route has been injected in Main App module.
Try routerLinkon button tag
<button type="button" [routerLink]="['/edit']">Edit</button>
More Info
in your html file right this code.
<button (click)="btnClick()">Cancel</button>
in your component.ts file right this code.
constructor(private router:Router) { }
btnClick(){
this.router.navigateByUrl("/payment");
}
window.location.reload();
does the trick

Categories

Resources