Navigating through nested components in Angular

I built a navigation bar component with a single routerLink:

 <p>
  <a routerLink="/user">User</a>
</p>

In the UserComponent, there is a nested component where I pass a value:

@Component({
  selector: 'app-user',
  template: `
    <input #box (keyup.enter)="onEnter(box.value)">
    <div *ngIf="box.size > 0">
      <app-order [value]="value"></app-order>
    </div>`

})
export class UserComponent implements OnInit {

  value = '';

  onEnter(value: string) {
    this.value = value;
  }

  constructor() {
  }

  ngOnInit() {
  }

}

The OrderComponent looks like this:

@Component({
  selector: 'app-order',
  template:`{{id}}`
})
export class OrderComponent implements OnInit {

  @Input() id:String;

  constructor() { }

  ngOnInit() {
  }

}

Currently, when I click on the user link, I see the view with the passed value. If I click the link again, it retains the same value. How can I modify this behavior so that clicking on the route button again resets the input value?

Answer №1

Encountering the same issue of refreshing a page upon clicking its corresponding button on the navbar has been a challenge.

The state of the application in Angular remains unchanged when navigating to the same URL, causing no effect according to Angular's logic.

To address this issue, there is a workaround available through the onSameUrlNavigation option.

Although this option triggers guards and resolvers upon navigating to the same URL, activating it may not yield noticeable results.

To tackle this issue personally, I devised a custom workaround by creating a specific class:

/** * Abstract class that enables derived components to automatically refresh upon route change. * The intended use case is: updating a page by navigating to the same URL while ensuring rendered components are refreshed. */ export abstract class AutoRefreshingComponent implements OnInit, OnDestroy { public routerEventsSubscription: Subscription; protected router: Router; constructor() { this.router = AppInjector.get(Router); } /** * Initialization behavior. Derived classes must avoid implementing OnInit directly. * Instead, utilize initialize() in derived classes. */ ngOnInit() { this.initialize(); this.routerEventsSubscription = this.router.events.filter(x => x instanceof NavigationEnd).subscribe(res => { this.initialize(); }); } /** * Destruction behavior. Derived classes should not implement OnDestroy directly. * Use destroy() in derived classes instead. */ ngOnDestroy(): void { this.routerEventsSubscription.unsubscribe(); this.destroy(); } /** * Function for derived components to define initialization behavior */ abstract initialize(): void; /** * Function for derived components to define destruction behavior */ abstract destroy(): void; }

AppInjector is referenced as follows:

import {Injector} from '@angular/core'; /** * Enables retrieval of singletons using `AppInjector.get(MyService)` (compared to creating a new instance with `ReflectiveInjector.resolveAndCreate(MyService)`). */ export let AppInjector: Injector; /** * Tool for accessing the exported {@link AppInjector}, necessary since ES6 modules export immutable bindings; refer to http://2ality.com/2015/07/es6-module-exports.html */ export function setAppInjector(injector: Injector) { if (AppInjector) { // Error check console.error('Programming error: AppInjector was already set'); } else { AppInjector = injector; } }

In your AppModule:

import { setAppInjector } from './app.injector'; // ... export class AppModule { constructor(private injector: Injector) { setAppInjector(injector); } }

Ensure all required components extend AutoRefreshingComponent.

In your situation: @Component({ selector: 'app-user', template: ` <input #box (keyup.enter)="onEnter(box.value)"> <div *ngIf="box.size > 0"> <app-order [value]="value"></app-order> </div>` }) export class UserComponent extends AutoRefreshingComponent { value = ''; onEnter(value: string) { this.value = value; } constructor() { } initialize() { // Reset your box value } destroy() { } }

This approach might seem extensive for your current requirements, but it proves beneficial whenever you need to refresh a component during same URL navigation.

Feel free to reach out if you find this useful.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Validating multiple conditions in Typescript by passing them as function parameters

As a beginner in TS/JS, I am looking to validate multiple conditions passed as arguments to a function. For instance, currently I am verifying the user role name, but in the future, I may need to check other conditions. validateUserDetails(): Promise< ...

Struggling to find a way to make Istanbul disregard the Angular @Input set function

I'm having trouble figuring out how to ignore a specific input set function in ng2. Can anyone provide guidance on this issue? Thanks! /* istanbul ignore next */ @Input() set pageOffset(pageOffset: number) { this.pageOffsetSetter(pageOffset); } ...

Mismatch in TypeScript React Intl Redux form types encountered

Currently, I am facing an issue trying to connect my form to Intl and struggling with a TypeScript error. The error seems to disappear when I change injectIntl<any>, but then I'm not sure what exactly needs to be passed there. Can someone please ...

How can I simulate keyboard events in Angular using a button click?

I've included separate buttons for Ctrl+z and Ctrl+y functionalities. When these buttons are clicked, I want them to perform the respective undo and redo actions programmatically. Below is the code snippet for this functionality. undoText(event:MouseE ...

Is it a Typescript error or is Typescript's checking not entirely accurate?

After years of experience with JavaScript, I recently decided to delve into TypeScript. Example 1 As I was developing, I discovered that const A : B = class B {} This code snippet would result in a warning "Cannot find name 'B'". However, the ...

Angular Form Template Unidirectional Data Binding Example

I'm facing a challenge with one-way binding to a default value in my HTML form. Within my component, I have a Connection string that is initially set from local storage: export class AuthAdminComponent implements OnInit { public authenticated = f ...

Transform a JavaScript time stamp by appending a time zone offset (+0800) to the end

Upon receiving a timestamp in the format of "2019-08-31T00:00:00+0800", I attempted to convert it into a date using JavaScript. However, the result was Fri, 30 Aug 2019 16:00:00 GMT instead of the desired date of 31 Aug 2019. I observed that there is a +0 ...

Vue3 and Typescript issue: The property '$el' is not recognized on type 'void'. What is the correct way to access every existing tag type in the DOM?

Currently, I am in the process of migrating a Vue2 project to Vue3 and Typescript. While encountering several unusual errors, one particular issue with $el has me puzzled. I have been attempting to target every <g> tag within the provided template, ...

The comparison between serialization at the PostgreSQL layer and the application layer

I have come across limited information and opinions on this topic. When it comes to serialization, is it better to perform it directly on the SQL layer (specific column selection) or is it acceptable for performance reasons to retrieve the entire record ( ...

Combining various outcomes into a single entity for ion-slide in Ionic 2

I am facing a similar issue with this problem, but with a different twist. I want to showcase three results in ion-slide, and while iDangero Swipper seems like a solution, I believe ion-slide could also achieve something similar to this. Please take a look ...

Stopping HTTP client calls in OnDestroy hook of an Angular Service

Is it possible to automatically unsubscribe from an http call in an Angular service using the ngOnDestroy hook? Just to note, I am already familiar with using the rxjs 'take' operator or manually unsubscribing from the service within the compone ...

Unable to retrieve base64 pdf file due to network connectivity problem

I am trying to download a base64 pdf file from local storage using vue3 typescript. Here is the code snippet I'm using: downloadPDF() { const linkSource = `data:application/pdf;base64,${'json.base64'}`; const downloadLink = ...

Mastering the implementation of limit and offset in your GET HTTP request

When making a GET request, I need to include parameters: offset: <number>, limit: <number>, and an optional parameter sortBy that accepts fields separated by commas. What is the best way to define the GET method? getData(limit: number, offset ...

When the async keyword is added, the return type in Typescript can vary

This situation is really puzzling to me. I wrote a function to calculate the number of documents in a collection getDocCount(): Promise<number> { return MyModel.countDocuments({}); } Everything seemed fine. However, when I removed async since I ...

The utilization of @ViewChildren within a service.ts file can lead to an undefined outcome

I'm facing an issue where I get an undefined error when using ViewChildren to find specific elements in a service. The problem arises because the service is used across multiple HTML files. Is there a way to properly load these children within the ser ...

The counterpart of the RxJS setTimeout operator

Looking for a RxJS operator alternative to set/clearTimeout in these circumstances: this.mouseEnterSubscription = this.mouseEnterStream .subscribe(() => { this.timeout = setTimeout(() => { void this.playVideo(); }, 500) }); this.mo ...

What is the best way to remove any objects in this array that have empty strings as values?

I have been developing a form using Angular 14. The form consists of a primary section, which includes the user's necessary information, and a secondary section where users can input additional data (an array of residences displayed in a table) befor ...

Type inference error in TypeScript occurs within a conditional statement when the condition relies on the output of a function call rather than a boolean expression

In my TypeScript code, I have a Linked List class that is working perfectly. The class includes a Node type and functions to add items to the list. type ListItem = number | string | object; class Node { private value: ListItem; private next: Node | nu ...

ng2-charts does not display the updated labels, it only shows the data

I am currently working on an Angular application using the ng2-charts package. In one of my components, I have a pie chart displaying data retrieved from the server. Here is the code snippet for that component: export class PieChartComponent implements On ...

Discover the wonders of accessing Google's API for finding nearby locations!

Looking to integrate the nearby places API from Google Maps. Check out the Google Maps Nearby Places API'KEY' When using the above link, it returns results. However, changing it to the following link: 'Here is an alternative link for dyna ...