Router duplicating my page components - Angular - javascript

I'm having some problems to add a back home button in my top nav-bar. I want it to reset my page to the initial state of the page.
this is my header.component.html where I want to implement a function to go back to home page.
<div class="topnav">
<a class="active" routerLink="">{{title}}</a>
</div>
I tried routing to home, but my page got duplicated (Showing the same component twice) and I don't now what to do. My page can't have refresh either, because I'm doing this for a job and one of the requirements is having a full SPA. I tried too the function destroyPlataform(), then navigate back to path=" ", that worked, but my page refreshes when I do it and I can't have refresh on my page.
my app-routing.module:
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { MoviesComponent } from './movies/movies.component';
const routes: Routes = [{ path: '', component: MoviesComponent }];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
I'm working with The Movie DB API, and in my page are some cards, it allows search for movies, multiple pages showing these cards and I need this home button to return to the first page, or to leave the search results.
I only have two components, the header.component that has the button to reset the current state of page and return to the initial state (not working) and the movies.component that show the movie cards, search for movies by name and have pagination. I need the back home function to reset the search name and return to the initial state of the application.
For more information of how I show my movies:
movies.component.ts:
//Showing page on application and redirection
getMovies(page: number) {
this.moviesService
.getMovies(this.movieName, this.currentPage)
.subscribe((paramName) => {
page = this.currentPage;
if (this.movieName) {
this.searchMovies(this.movieName, this.currentPage);
}
if (page) {
this.currentPage++ || this.currentPage--;
}
this.totalPages = (paramName as any).total_pages;
this.movies = (paramName as any).results;
});
}
//Search functions bellow
//search by query
searchMovies(query: string, page: number) {
this.moviesService.searchMovies(query, page).subscribe((response) => {
query = this.movieName;
page = 1;
this.totalResults = (response as any).total_results;
this.movies = [];
this.movies = response['results'];
});
}
//send value of query to the search function
queryListener(value: string): void {
this.movieName = value;
this.currentPage = 1 + 1;
this.searchMovies(value, 1);
}
//End of search functions
movies.service.ts:
//Redirects
getMovies(query: string = '', page: number) {
if ((query = '')) {
return this.discoverMovies(page);
}
if (query) {
return this.searchMovies(query, page);
}
return this.discoverMovies(page);
}
this next method is inside the movies.service.ts too, and I want to go back to him to see the discover cards when I click on the home button
//Show the list of movies more recent by popularity
discoverMovies(page: number) {
let discover = `${this.discoverUrl}?api_key=${this.apiKey}&language=${this.language}&sort_by=popularity.desc&include_adult=false&include_video=false&page=${page}`;
return this.http.get(discover);
}
A simple 'href="localhost:4200/"' would help, but when I use href the page refreshes. I hope someone can help me!

Try using:
<div class="topnav">
<a class="active" [routerLink]="['/']">{{title}}</a>
</div>

Related

Preserve dynamically added <title> in Angular while reloading page

Is there a possibility when refreshing the page to save the tag that has been dynamically added ?
Now, the moment I refresh the page, while loading, the title tag changes to the original one, which I set in the index.html. When the page is loaded, the title tag then comes back to the correct one which is dynamically added. But, I want the title tag to stay the same while the page is refreshing.
This is my app.component.ts:
this.router.events.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) route = route.firstChild;
return route;
}),
filter((route) => route.outlet === 'primary'),
mergeMap((route) => route.data)
)
.subscribe((event) => {
console.log(event)
this.translateService.get(event['title']).subscribe(name => {
this._seoService.updateTitle(name);
});
this._seoService.updateDescription(event['description'])
});
One approach is to make use of Local Storage to store your dynamic title in there. Here's a simple example where I am storing the title in Local storage and refreshing the page, and retaining my title back. Angular provides a service called Title that allows us dynamically update the title anytime.
<button (click)="setItem()">Click to set a title</button>
<p *ngIf="showInfo" >Refresh the page now :)</p>
export class AppComponent implements OnInit {
showInfo = false;
constructor(private titleService: Title) {}
ngOnInit() {
this.getItem();
}
setItem() {
localStorage.setItem('title', 'Hey World!');
this.showInfo = true;
this.getItem();
}
getItem() {
if (localStorage.getItem('title'))
this.titleService.setTitle(localStorage.getItem('title'));
else this.titleService.setTitle('No title');
}
}
Here's a live application.
Code - Stackblitz

Keep data in page after refresh in angular

when i open my website i will see "Finance/voucher" on topenter image description here but when i refresh the page only "Finance" Appears and i don't want this i want when i refresh page still it will show "Finance/voucher" And all relevant code i have posted plz guide me which code i enter and where
export class TopBarComponent extends AppComponentBase {
formName = ""
constructor(
injector: Injector,
private _formTitleService: FormTitleService,
) {
super(injector);
}
ngOnInit() {
this.getFormTitle();
}
getFormTitle(){
this._formTitleService.getFormTitle()
.subscribe(name => {
this.formName = name;
});
}
Html code
<div class="page-title">
/ <span>{{formName}}</span>
</div>
You can set the initial value for formName = "Finance/voucher" in your component & it will be retained on page refresh.

Reload page after 3 seconds with a promise in Angular

I'm trying to implement a solution for the login page. When user passes the wrong login/password I want the page to reload after 3 seconds. I was trying to do it with 2 solutions but can't make it work. The code would launch after click on a button when there is no match for credentials (else condition):
FIRST IDEA:
...else{
this.comUser = 'WRONG LOGIN OR PASSWORD'
this.alert = ""
setTimeout(function() {
window.location = "I would like it to use the routing to a component instead of URL here"; }
,3000);
SECOND IDEA WITH A PROMISE:
const reloadDelay = () => {
reload = this.router.navigate(['/login']);
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("działa");
resolve(reload)
}, 4000);
});
};
Thanks for any hints!
If you're using angular 9 you can try this
setTimeout(() => {this.domDocument.location.reload()}, 3000);
You need to import:
import { Inject } from '#angular/core';
import { DOCUMENT } from '#angular/common';
In order to use the above-mentioned method and have the constructor of component.ts configured as below.
constructor(#Inject(DOCUMENT) private domDocument: Document){}
This can now be done using the onSameUrlNavigation property of the Router config. In your router config enable onSameUrlNavigation option, setting it to reload . This causes the Router to fire an events cycle when you try to navigate to a route that is active already.
#ngModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})],
exports: [RouterModule],
})
In your route definitions, set runGuardsAndResolvers to always. This will tell the router to always kick off the guards and resolvers cycles, firing associated events.
export const routes: Routes = [
{
path: 'invites',
component: InviteComponent,
children: [
{
path: '',
loadChildren: './pages/invites/invites.module#InvitesModule',
},
],
canActivate: [AuthenticationGuard],
runGuardsAndResolvers: 'always',
}
]
Finally, in each component that you would like to enable reloading, you need to handle the events. This can be done by importing the router, binding onto the events, and invoking an initialization method that resets the state of your component and re-fetches data if required.
export class InviteComponent implements OnInit, OnDestroy {
navigationSubscription;
constructor(
// … your declarations here
private router: Router,
) {
// subscribe to the router events. Store the subscription so we can
// unsubscribe later.
this.navigationSubscription = this.router.events.subscribe((e: any) => {
// If it is a NavigationEnd event re-initalise the component
if (e instanceof NavigationEnd) {
this.initialiseInvites();
}
});
}
initialiseInvites() {
// Set default values and re-fetch any data you need.
}
ngOnDestroy() {
if (this.navigationSubscription) {
this.navigationSubscription.unsubscribe();
}
}
}
With all of these steps in place, you should have route reloading enabled. Now for your timeperiod, you can simply use settimeout on route.navigate and this should reload it after desired time.

Data Sharing between Angular components

I am new in angular 6. I am creating a project using angular 6. I am coming in to a problem while sharing the data. Here is the project structure:
1) Header Component
2 Login Component
3) Home Component
4) Shared Service
I am adding the class in my header component on the basis of current route.
This was working on page refresh. But when i move from one component to other this was not working.
Here is the code:
Layout Component is:
<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>
</div>
Header Component:
ngOnInit() {
console.log(this.dataService.urlExists())
if(this.dataService.urlExists()){
this.url = true
}else{
this.url = false
};
}
<header class="stick-top forsticky" id="header" [ngClass]="{'gradient': url==true}">
</header>
Shared Service:
urlExists(){
this.url = this.router.url
if(this.url == "/"){
return false;
}else{
return true;
}
}
Please note: On page refresh this is working..
It is because, your header component is not reinited when navigating as it is outside of router-outlet. You need to listen route changes and perform desired operations accordingly.
So in the Header Component, you can subscribe to router events and listen NavigationEnd events to check URL:
import {NavigationEnd, Router} from '#angular/router';
import {filter} from 'rxjs/operators';
...
constructor(private router: Router) {
this.subscribeRouterEvents();
}
subscribeRouterEvents = () => {
this.router.events.pipe(
filter(e => e instanceof NavigationEnd)
).subscribe(() => {
console.log(this.dataService.urlExists())
if(this.dataService.urlExists()){
this.url = true
}else{
this.url = false
};
});

Update values when sending to another component Angular 2

I'm using routerLink to send an id from a component with a list of restaurants to another component via URL
[RouterLink] = "['../ restaurant-menu', restaurant.id]"
In the other component I use the id as follows
ngOnInit () {
this.restaurantId = this.router.snapshot.params ['id']
this.getRestaurantMenu (this.restaurantId)
}
restaurantMenu: void []
getRestaurantMenu (id): void {
this.RestaurantsService.getRestaurantMenu (id)
.subscribe (
restaurantMenu => this.restaurantMenu = restaurantMenu,
err => {
console.log (err);
});
}
Everything works fine the first time I click a restaurant and load its menu, the problem begins when I return to the list of restaurants and click a different restaurant, the app loads the menu of the first restaurant I clicked, I have to refresh the browser Manually to load the correct menu.
I doubt that the id could be updated after calling the function getRestaurantMenu() because no matter how many times I leave and enter into different restaurants it will always show the menu of the first restaurant, but I also tried to do this on the HTML:
<P> {{restaurantId}} </ p>
And the id number displayed is correct. I tried different ways to pass that id but the result is the same, what could be the problem? Thanks
Maybe try not to use snapshot but ActivatedRoute instead :
import { ActivatedRoute, Params } from "#angular/router";
...
constructor(private route: ActivatedRoute) { }
...
ngOnInit() {
// (+)param['id'] to convert string to number
this.route.params
.switchMap((param: Params) => this.RestaurantsService.getRestaurantMenu(+param['id']))
.subscribe(
restaurantMenu => this.restaurantMenu = restaurantMenu,
err => console.log (err)
);
}
I did what is suggested here
https://github.com/angular/angular/issues/9811#issuecomment-264874532
the restaurantMenu component stays the same but in the restaurantList component I added this:
import { Router } from '#angular/router';
...
openMenu(restaurant) {
this.router.navigate(['../restaurant-menu', restaurant])
.then(() => window.location.reload())
}
and on the restaurantList HTML I added a (click)="openMenu(restaurantId)" It reloads the new page automatically and the id is updated, its a little tricky solution but works and I'll use it until find a better one.
I finally solve this, the problem was in the service to get the menu not in the component, here is the solution:
angular 2 service is not updating params
if anybody else run into this problem this may help.

Categories