Preventing an Angular component from continuing to execute after clicking away from it

At the moment, I have a sidebar with clickable individual components that trigger API calls to fetch data. However, I've noticed that even when I click off a component to another one, the old component continues to refresh the API data unnecessarily.

Below is a sample test component. It displays "test component is still active" when clicked on. Even after clicking off the component, it still shows this message, indicating that the component is still running. Is there a way to stop the component once it's no longer being used? Or perhaps there's a more efficient method for obtaining fresh data?

export class TestComponent implements OnInit {

userActivity;

  constructor(
  ) { }

  ngOnInit() {
    this.refreshData();
  }

  refreshData(){
    this.userActivity = setTimeout(() => {
      // where api data is called out
      console.log('test component is still active');
      this.refreshData();
    }, 5000);
  }
}

Answer №1

Dealing with asynchronous code, like subscriptions or setTimeout() within Angular components, can lead to common problems. Angular does not automatically handle the unsubscribing or termination of such asynchronous code - it is the responsibility of the programmer.
There are several approaches to address this issue based on the specific scenario. In your situation, you have already saved the timeout handle returned by setTimeout in userActivity. You can utilize this handle to clear the timeout using Angular's OnDestroy lifecycle hook. Consider OnDestroy as the complement to OnInit, as it is triggered when a component is destroyed.

export class TestComponent implements OnInit, OnDestroy {
  userActivity;

  constructor() {}

  ngOnInit() {
    this.refreshData();
  }

  refreshData() {
    this.userActivity = setTimeout(() => {
      // calling API data
      console.log('test component is still active');
      this.refreshData();
    }, 1000);
  }

  ngOnDestroy() {
    clearTimeout(this.userActivity);
  }
}

You can observe this solution in action on this Stackblitz example. By monitoring the console output, you will notice that the console.log stops appearing once you switch from component 1 to component 2.

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

Error: The identifier HTMLVideoElement has not been declared

Encountering an issue while attempting to build my Angular 9 Universal project for SSR: /Users/my-project/dist/server.js:28676 Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:type", HTMLVideoElement) ReferenceError: HTMLVideoElem ...

Discovering the Cookie in Angular 2 after it's Been Created

My setup includes two Components and one Service: Components: 1: LoginComponent 2: HeaderComponent (Shared) Service: 1: authentication.service Within the LoginComponent, I utilize the authentication.service for authentication. Upon successful authent ...

passing data through URL in Angular 7

Looking to pass a parameter in the URL while using Angular 7, to achieve a format like example.com/search/users?q=tom. Below is the syntax I am currently using in my service: public searchUsers(obj):any{ return this._http.get('example.com/s ...

What is the best way to ensure a specific row remains at the bottom of an Angular table with Material when sorting?

My data table contains a list of items with a row at the end showing the totals. | name | value1 | value2 | --------------------------- | Emily | 3 | 5 | | Finn | 4 | 6 | | Grace | 1 | 3 | | TOTAL | 8 | 14 | I&apos ...

Exploring the integration of external javascript AMD Modules within Angular2 CLI

During my experience with Angular2 pre-releases, I found myself using systemjs to incorporate external JavaScript libraries like the ESRI ArcGIS JavaScript API, which operates on AMD modules (although typings are available). Now that I am looking to trans ...

Displaying data from a service on an Ionic screen: a comprehensive guide

I've retrieved JSON data from an API: { "userGroups":[ {"title":"group 1"}, {"title":"group 2"}, {"title":"group 3"}, {"title":"group 4"} ] } Currently, I am storing this raw data in NativeStorage. // userService this.userGroup ...

What is the best way to perform a deep copy in Angular 4 without relying on JQuery functions?

Within my application, I am working with an array of heroes which are displayed in a list using *ngFor. When a user clicks on a hero in the list, the hero is copied to a new variable and that variable is then bound to an input field using two-way binding. ...

The Context API's `useContext` hook appears to be malfunctioning, persistently

My situation is as follows: export const LocationContext = createContext(null); export const LocationProvider = LocationContext.Provider; export const useLocationContext = () => useContext(LocationContext); Using the Provider: export const Search = () ...

Whenever signing in with Next Auth, the response consistently exhibits the values of "ok" being false and "status" being 302, even

I am currently using Next Auth with credentials to handle sign-ins. Below is the React sign-in function, which can be found at this link. signIn('credentials', { redirect: false, email: email, password: password, ...

Aligning validation schema with file type for synchronization

Below is the code snippet in question: type FormValues = { files: File[]; notify: string[]; }; const validationSchema = yup.object({ files: yup .array<File[]>() .of( yup .mixed<File>() .required() .t ...

Tips for adjusting HighCharts layout with highcharts-vue integrations

I have a fairly simple component: <template> <div> <chart v-if="!loading" ref="priceGraph" constructor-type="stockChart" :options="chartData" ...

The Step-by-Step Guide to Deselecting an Angular Checkbox with a Button

I currently have a situation where I have three checkboxes labeled as parent 1, parent 2, and parent 3. Initially, when the page loads, parent 1 and parent 3 are checked by default, while parent 2 is unchecked. However, when I manually check parent 2 and c ...

AngularJS Currency Converter - Converting Currencies with Ease

I have a question regarding the most efficient way to handle currency conversion on a webpage. Currently, I have multiple input fields displaying different currencies. When a user clicks on the currency conversion button, a modal popup appears. After the ...

What is the correct way to use Observables in Angular to send an array from a Parent component to a Child

Initially, the task was to send JSON data from the parent component to the child component. However, loading the data through an HTTP request in the ngOnInit event posed a challenge as the data wasn't being transmitted to the child component. Here is ...

Is Angular9 BehaviorSubject from rxjs giving trouble across different components?

I am facing an issue with updating data in real-time from the profile component to the header component. Initially, it works fine but after updating any value in the profile component, the header observable does not subscribe again. To solve this problem, ...

Troubleshooting issue with image dimensions in Angular within CKEditor content

One issue I am facing is with CKEditor, where images inserted into Rich Text Fields have their height and width attributes set in a CSS style tag. For example: <img alt="" src="https://something.cloudfront.net/something.jpg" style="height:402px; ...

What is the best way to declare a TypeScript type with a repetitive structure?

My data type is structured in the following format: type Location=`${number},${number};${number},${number};...` I am wondering if there is a utility type similar to Repeat<T> that can simplify this for me. For example, could I achieve the same resul ...

Hovering over the Star Rating component will cause all previous stars to be filled

I'm in the process of creating a Star Rating component for our website using Angular 11. I've managed to render the 5 stars based on the current rating value, but I'm having trouble getting the hover styling just right. Basically, if I have ...

Saving the name and corresponding value of a selected option element into separate fields using Angular framework

I have implemented the following code to generate a select field. The ngModel is successfully updating the value, but I am also looking to capture the name of the selected option and store it in a different field. Is there a solution to achieve this? ( & ...

What advantages can be gained by opting for more precise module imports?

As an illustration, consider a scenario where I have an Angular 6 application and need to bring in MatIconModule from the @angular/material library. Two options could be: import { MatIconModule } from '@angular/material/icon'; Or import { Mat ...