Exploring the Relationship Between the ngOnInit and ionViewWillLoad Lifecycle Hooks

After a few months of utilizing Ionic Framework (ionic-angular 3.9.2 latest) for developing Progressive Web Apps, I find myself pondering the distinction between ngOnInit and ionViewWillLoad.

If my understanding serves me right, ngOnInit is an Angular lifecycle hook responsible for initializing directives and components. (Setting input properties of the directive/component.)

ionViewWillLoad, on the other hand, is an Ionic navigation lifecycle event, which appears to run before the ionViewDidLoad event that signifies everything has been loaded. Interestingly, it seems that the ionViewWillLoad event has not been added to NavController, as indicated by the lack of documentation update.

As per my knowledge, the constructor is invoked by the JavaScript engine and should be steered away from complex initializations. (details: why you should avoid complex constructor logic)

Hence, I opted to utilize ionViewWillLoad to configure the component after Ionic sets the input properties.

Interestingly, ionViewWillLoad was the only event that functioned smoothly without any errors.

export class UsernamePage {
  usernameControl: FormControl;

  constructor(private userService: UserServiceProvider){ }

  // No errors
  ionViewWillLoad() { this.createUsernameForm(); }

  // Errors
  ionViewWillEnter() { this.createUsernameForm(); }
  ionViewDidEnter() { this.createUsernameForm(); }
  ionViewDidLoad() { this.createUsernameForm(); }

  createUsernameForm() {
    this.usernameControl = new FormControl('',
    {
      validators: [Validators.required, Validators.minLength(4)],
      asyncValidators: CustomValidator.username(this.userService)
    });
  }
}

Should I continue using ionViewWillLoad? Or would it be more beneficial to implement the OnInit interface? What sets them apart?

Answer №1

Just a heads up: In Ionic V3, I tend to use the terms "hooks" and "events" interchangeably when talking about the lifecycle methods.

After some investigation, it appears that ionViewWillLoad is not included in the latest version of Ionic V3's lifecycle hooks. If there are other errors you're encountering with different lifecycle events, I'd love to hear more specifics. But for now, let's delve into a couple of fundamental questions:

1) What sets Angular's ngOnInit apart from Ionic's ionViewDidLoad? Is there a clear advantage to using one over the other?

Interestingly enough, Angular's ngOnInit and ngOnDestroy hooks display similarities to Ionic's ionViewDidLoad and ionViewWillUnload events (respectively). These get triggered only when a page is created or removed, which may not occur as frequently due to Ionic's page caching for improved mobile performance.

In child/sub components within V3, Angular's lifecycle hooks are your sole option. For page-level components in V3 (i.e., components managed by a NavController), you can opt to use either set of hooks interchangeably. However, it's advisable to stick with one or the other, not both, for consistency. Notably, Ionic V4 simplifies this decision by removing ionViewDidLoad and ionViewWillUnload.

2) How do Angular's ngOnInit and Ionic's ionViewWillEnter compare? Is one preferable over the other?

It's important to note that these comparisons primarily relate to page-level components since Ionic Lifecycle Events are exclusive to such components (as outlined in the V3 documentation). Subcomponents won't interact with Ionic Lifecycle Events because they aren’t controlled by the NavController, potentially explaining any error messages you've encountered.

The key distinction between these two events lies in their firing sequence and frequency. Upon a page-level component's creation, ngOnInit executes before ionViewWillEnter. Nonetheless, pages might not necessarily be destroyed unless removed from the navigation stack, as per the V3 documentation.

By default, pages remain cached in the DOM when navigated away from but kept in the navigation stack (e.g., the exiting page during a push()). They are disposed of upon being removed from the navigation stack (via pop() or setRoot()).

Neither event holds absolute superiority over the other. Implementing both is feasible, though bear in mind that ngOnInit may not trigger as consistently or regularly as expected; whereas, ionViewWillEnter activates whenever the page transitions to become the active one.

About Ionic V4 (Angular)

Lifecycle events adopt a simpler structure in V4. We observe fewer Ionic lifecycle events, devoid of overlap with Angular equivalents like in V3. Detailed explanations and practical guidance on utilizing Angular and Ionic lifecycle aspects are available in the docs.

The core insights parallel those applicable to V3.

Pages exclusively exit the DOM when "popped," such as via the UI back button or browser's back command.

This distinctive handling implies that ngOnInit and ngOnDestroy might not fire at anticipated instances.

ngOnInit triggers solely upon fresh page creation, not upon revisitation. For instance, navigating across tabbed interfaces will invoke each page's ngOnInit only once, excluding subsequent visits. ngOnDestroy materializes strictly upon page "pop" actions.

Answer №2

When working with Ionic 3, it is recommended to utilize the following methods:


ionViewWillEnter () {
    console.log('This function is executed every time the view is entered');
}

This method should be used for tasks that need to be performed each time, such as accessing updated data or updating a table.


ionViewDidLoad () {
    console.log('This function is not called when entering a cached view');
}

ionViewDidLoad() is suitable for initialization tasks that do not need to be repeated each time, as it is not triggered when entering a view that is already cached.

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

What is the best way to dynamically insert values into a JSON object?

I'm currently working with a JSON object in Angular and I need to dynamically add values that the user enters. Despite searching extensively, I haven't found a straightforward method to achieve this. I simply want to understand how to append key- ...

DotLottie file loading issues

While using dotlottie/react-player, webpack 4, and react 16, I encountered module parse failed errors during compilation. "@dotlottie/react-player": "^1.6.5" "webpack": "^4.44.2", "react": "16.14.0&qu ...

Angular: Failure in receiving EventEmitter's event with .subscribe method

My current challenge involves handling an event coming from NgLoopDirective within the method EV of NgDNDirective. I am attempting to achieve this by passing the EventEmitter object by reference and then calling .subscribe() as shown in the code snippet be ...

Encountering an error with Dynamic Control generic react-hook-form: Error code TS2322 appears - Type 'Control<FormFields, any>' cannot be assigned to type 'Control<FieldValues, any>'

Within my application, I am utilizing react-hook-form in conjunction with the latest version of MUI 5.11. I have developed a reusable Select component: ...someImports import { Control, Controller } from 'react-hook-form'; interface SelectProps { ...

Optimizing Angular: Configuring baseHref for assets during development with SSR

During production, we set the base href using the following command: ng build --base-href /app/ This configuration works smoothly as our assets are also accessible at /app/assets/, just as expected. However, I have been facing difficulties achieving the ...

Implement code to execute exclusively on the initial success of react-query

I have a unique scenario where I need to utilize standard useQuery behavior, while also executing a piece of code only on the initial onSuccess event. Although I understand that I can accomplish this using useRef, I am curious if there is an alternative a ...

Creating a JSON utility type for an already existing type, such as JSON<SomeExistingType>

Is there any tool or utility available that can accomplish this task? const foo: Foo = { ... } const bar: string = JSON.stringify(foo) const baz: JSON<Foo> = JSON.parse(foo) JSON<Foo> would essentially mirror all the properties of Foo, with th ...

Leverage classes within components for effective dependency injection

Currently, I am working with Angular and have set up 1 component, 1 class, and 1 service in my project. The service is defined as an @Injectable class and properly configured in app.module.ts. @Injectable() export class MyService { My class receives the ...

The error "Cannot access property afs (Angularfirestore) of undefined in the collection.set()" occurred

In the current code snippet below, I am iterating over a collection of data and updating a field if the email matches. The issue arises when trying to set new values where it crashes. The iteration process itself functions correctly, with afs being Angular ...

Navigating the complexities of managing numerous checkboxes in React

I am a beginner with react and recently received a task to complete. The requirements are: Show multiple checkboxes. The order of checkbox names may change in the future, allowing the client to decide the display order. Display checkboxes based on their a ...

Exploring the Concept of Extending Generic Constraints in TypeScript

I want to create a versatile function that can handle sub-types of a base class and return a promise that resolves to an instance of the specified class. The code snippet below demonstrates my objective: class foo {} class bar extends foo {} const someBar ...

Having trouble finding the right path. Is there an issue with Angular routing?

After successfully creating a simple application, I decided to write test cases for it. My first attempt was to work on the routing part of the application. Check out the code on StackBlitz The routing code snippet is as follows: Main module: export cons ...

Create a function that is identical to the original, but omits the final

I am currently working on defining a type B that functions similarly to type A, but without the last parameter. I have attempted the solution below, however, it is still requiring 2 parameters instead of just one. type Callback = (msg: string) => void; ...

At what point is the ngOnInit function invoked?

Here is the code snippet I am working with: <div *ngIf="hotels$ | async as hotels; else loadGif "> <div *ngFor="let hotel of hotels | hotelsFilter: _filteredType; first as f; index as i " appInit [hotel]="hotel " [first]="f "> < ...

Exploring the implementation of a custom validator within an Angular service

I have been attempting to implement a custom validator to validate if an email is already in use. After consulting the documentation and reading various articles, I have come up with the following code: In my auth.service.ts file checkEmail(email) { ...

What is the best way to incorporate infinite scrolling into my Angular carousel implementation?

After following an amazing tutorial, I was able to create a basic carousel using two directives and one component in Angular. However, the current version of the carousel lacks an 'infinite scrolling' mode, which is something I would like to inc ...

Ensuring Data Consistency: Using TypeScript to Strongly Type Arrays with Mixed Variable Types

I have a JSON array that may contain objects of two types, defined by IPerson and ICompany. [ { "Name" : "Bob", "Age" : 50, "Address": "New Jersey"}, { "Name" : "AB ...

Finding the solution to the perplexing issue with Generic in TypeScript

I recently encountered a TypeScript function that utilizes Generics. function task<T>(builder: (props: { propsA: number }, option: T) => void) { return { run: (option: T) => {}, } } However, when I actually use this function, the Gener ...

Unable to resolve all parameters for the createRouterScroller function in Angular routing

Just starting out with Angular routing and added the package to my Ionic project using npm i @angular/router Encountering some errors after adding appRoutes to app.modules.ts RouterModule.forRoot( appRoutes, { enableTracing: true } // <-- for d ...

Unable to construct a node typescript project using solely production dependencies

I am currently working on a Node TypeScript project that utilizes various third-party libraries such as express. To ensure type safety, I typically install the @types/express module as a dev dependency following common instructions. The installation works ...