Angular 2: The ngOnInit method will be executed after attempting to render the template when initiating from a URL containing an identifier

I'm currently developing an angular application that utilizes the Router to navigate between multiple components starting from AppComponent. In order to demonstrate the issue I am facing, I have created a simplified version on plunker (Interestingly, the code runs without any problems locally but encounters issues on plunker.)

When the application is accessed from either http://localhost:3000 or http://localhost:3000/home, everything works as intended when clicking on the links fruit1 and fruit2 which correctly changes the URL to http://localhost:3000/fruit/1 with the corresponding description text. However, the problem arises when directly accessing the URL http://localhost:3000/fruit/1 (typing it in the browser and hitting enter), it appears that the service call within the ngOnInit of the fruit-detail.component.ts occurs AFTER attempting to render the HTML component, resulting in the following stack trace:

EXCEPTION: TypeError: Cannot read property 'description' of null in [ desc: {{fruit.description}}  in FruitDetailComponent@1:6]
angular2.dev.js:23925 EXCEPTION: TypeError: Cannot read property 'description' of null in [ desc: {{fruit.description}}  in FruitDetailComponent@1:6]BrowserDomAdapter.logError @ angular2.dev.js:23925BrowserDomAdapter.logGroup @ angular2.dev.js:23936ExceptionHandler.call @ angular2.dev.js:1320(anonymous function) @ angular2.dev.js:12857schedulerFn @ angular2.dev.js:13264SafeSubscriber.__tryOrUnsub @ Rx.js:10775SafeSubscriber.next @ Rx.js:10730Subscriber._next @ Rx.js:10690Subscriber.next @ Rx.js:10667Subject._finalNext @ Rx.js:11191Subject._next @ Rx.js:11183Subject.next @ Rx.js:11142EventEmitter.emit @ angular2.dev.js:13245NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ angular2.dev.js:13666NgZoneImpl.inner.inner.fork.onHandleError @ angular2.dev.js:2143ZoneDelegate.handleError @ angular2-polyfills.js:394Zone.runGuarded @ angular2-polyfills.js:300NgZoneImpl.runInner @ angular2.dev.js:2155NgZone.run @ angular2.dev.js:13749(anonymous...
and so on...

<p>Subsequently, the console logs the message "got fruit inside fruitComponent !apple", reinforcing my suspicion that ngOnInit is called after rendering. How can I ensure that the app functions properly even when directly loading from the 'fruit/1' URL? Any assistance would be greatly appreciated. Thank you!</p>

<pre><code>===== extract data called!!
fruit-detail.component.ts:25 got fruit inside fruitComponent !apple

Answer №1

To ensure data availability with asynchronous execution, consider using the elvis operator:

<h2> desc: {{fruit?.description}} </h2>

When executing this._foodService.getData() asynchronously, the result is obtained after the completion of the ngOnInit method.

If routing is utilized, the OnActivate interface along with its routerOnActivate method may be suitable. By returning a promise within this method, the component will wait for resolution before proceeding with route changes. This ensures that the data is available upon component display, preventing any related issues.

For implementation reference, refer to the following example:

@Component({
  (...)
})
export class FruitDetailComponent implements OnInit, OnActivate {
  fruit = null;

  constructor(
    private _rbacService: FoodService,
    private _routeParams: RouteParams) {}

  routerOnActivate(next: ComponentInstruction,
                   prev: ComponentInstruction) {
    return new Promise(resolve => {
      let id = +this._routeParams.get('id');
      console.log('on init fruit component: id = '+id);
      
      this._rbacService.getData().subscribe(data =>{
        this.fruit = data['fruits'].filter(obj => obj.id === id)[0];
        console.log('got fruit inside fruitComponent '+this.fruit.description);
        resolve(null);
      })
    });
  }
}

Additional information can be found at:

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

Reinforced.Typings does not generate fully qualified names (FQN) for types when UseModules is set to true or false

Overview: Within my solution, I have two projects: ProjA and ProjB. In ProjA, I've defined a custom RTConfigure method to streamline the configuration process for translating C# to TypeScript using the Reinforced.Typings tool. Meanwhile, ProjB houses ...

Calling the ngSubmit.emit() function does not alter the submitted property within the formGroup

When dealing with two forms that require validation before being shown to the user, the challenge lies in triggering the submission of both forms simultaneously. This ensures that only the required fields are displayed for the user to fill out. Currently, ...

What is the best way to bring in local modules within the browser environment using Playwright?

Let me illustrate what I am attempting to achieve: ../src/Foo/Bar.ts represents a local TypeScript file This particular file contains code that is designed to function within a browser environment (it utilizes WebSockets), and therefore needs to be execu ...

M.E.A.N - Suite for setting up and defining backend boundaries consisting of MongoDB, Express.js, Angular2, node.js

Seeking knowledge on how the frameworks and platforms Angular 2 and Express.js collaborate in the 'mean' approach is my main query. I am interested in understanding where the client-side ends and the server-side begins. After delving into this t ...

Wrapper for Material UI - leverage TypeScript types for a specific property

Apologies if this question has been addressed previously as I was unable to locate an answer. Currently, the app I am developing utilizes a wrapper for certain material-ui components. For example, I have a MyCompanyButton component which acts as a wrapper ...

Navigating a relative path import to the correct `@types` in Typescript

When the browser runs, I require import * as d3 from '../lib/d3.js'; for d3 to be fetched correctly. I have confirmed that this does work as intended. However, the file that contains the above code, let's call it main.js, is generated from ...

Encountering a navCtrl problem in Ionic 3 while attempting to utilize it within a service

I am currently working on a feature to automatically route users to the Login Page when their token expires. However, I am encountering an issue with red lines appearing under certain parts of my code. return next.handle(_req).do((event: HttpEvent< ...

What is the best way to create an interactive experience with MapLibre GL in Full Screen mode?

Hello, I am seeking a solution to create a map with the interactive option set to false, but once in full screen mode, I need this parameter to be true. Do you have any suggestions or ideas on how to achieve this? const _map = new MapGL({ contai ...

The Angular Node server is responding with the error message "You have entered 'undefined' instead of a stream."

Using angular 9 + universal has been smooth sailing until I encountered an issue after building the app with npm run build:ssr and attempting to run it using node: node dist/app/server/main.js. The error message that popped up in the terminal was: Node ...

Issue with mat-selection-list search filter losing selections upon searching

Currently, I am working on incorporating a mat-selection-list that displays a list of characters. The unique feature is the ability to search and filter characters at the top of the list. Everything works smoothly except for one issue - when you select a c ...

Element is missing the necessary "key" property. (React and TypeScript)

Upon running the following code for reactJS and typescript, I encountered the error below: I have also included the import statement import 'bootstrap/dist/css/bootstrap.min.css'; in Index.tsx. Is there a solution to resolve this issue? npm s ...

Encountering a problem in Angular 2 when initiating a project

I recently started learning Angular 2. I set up my project and attempted to launch it using npm. Initially, everything was working smoothly, but after a few days, when I tried to start it again, an error appeared in the command prompt. SyntaxError: Unexpe ...

Guiding you through the process of dynamically defining a port in proxy.conf.json or proxy.conf.js

Starting my Angular4 application for development involves running npm run start, where start is defined as "start": "ng serve --proxy=proxy.conf.json". Within the proxy.conf.json file, I have: { "/api/**": { "target": "http://localhost:80 ...

Discover the return types in Typescript by inferring from a collection of functions within an

Imagine you have an object { num1: 1, num2: 2, str: "abc" } Your goal is to develop a function that accepts any similar object as the first parameter, and a custom selectors object as the second parameter. function fn<O extends object, ...

How can I extract a value from an object that is readonly, using a formatted string as the key?

I encountered a situation where I have code resembling the following snippet. It involves an object called errorMessages and multiple fields. Each field corresponds to various error messages in the errorMessages object, but using a formatted string to retr ...

Searching for several arrays in Angular

Hello everyone, I have an API that returns data like this: [ [{ "id": 1, "qte": 12, "date_creation": "2020-08-17T00:00:00+02:00", "date_update": "2020-08-17T00:00:00 ...

A comprehensive guide on integrating rappid.js and joint.js into an Angular 2 application

Exploring the possibility of integrating rappid and joint.js into a component of my Angular 2 application. Despite searching online, I haven't come across an example that fits my requirements. Is there a demo or guide available to show how this integ ...

Tips for eliminating hash from a URL in Angular 9

I have come across numerous queries similar to this one regarding Angular versions other than 9. I have successfully applied what I believe to be the fix, but I am curious if it has been altered in v9. index.html <head> <base href="/"> a ...

Mastering regular expressions in TypeScript

My goal is to perform linting on staged files that are either .ts or .tsx and located within the src folder. I am aware that for selecting all js files one can use "*.js": [--list of commands--] inside the lint staged property. I'm curious to learn m ...

What steps are needed to generate a production version of a TypeScript monorepo application that can be deployed to an Azure Function App?

I've been grappling with understanding Typescript project references and their intended use in a production build, especially for an Azure Function App. I'm not utilizing any monorepo functionality at the package manager level, such as npm worksp ...