Tips for resolving the issue with the message "ERROR TypeError: _co.loadedRecipe is undefined" and the error "ERROR Error: [object Object]"

Currently, I am in the process of learning Ionic and Angular while attempting to implement routing where information is passed through the path like this:

path: ':recipeId',

My goal is to have a list of items with IDs so that when I click on an item, I can navigate to a detailed page for that specific item.

I have successfully displayed the page with the list of items (let's say it's at /recipes), but upon clicking on an item to go to the detail page (/recipes/id), I encounter the following error:

ERROR TypeError: "_co.loadedRecipe is undefined" View_RecipeDetailPage_0 RecipeDetailPage.html:11 Angular 24 RxJS 5 Angular 11 RecipeDetailPage.html:11:4 View_RecipeDetailPage_0 RecipeDetailPage.html:11 Angular 16 RxJS 5 Angular 11

This points towards the module's (or component's? still learning Angular) HTML code:

<ion-header>
  <ion-toolbar>
    <ion-title> {{ loadedRecipe.title }} </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
    <ion-grid>
        <ion-row>
            <ion-col>
                <ion-img [src]="loadedRecipe.imageUrl"></ion-img>
            </ion-col>
        </ion-row>
        <ion-row>
            <ion-col>
                <h1> {{ loadedRecipe.title }}</h1>
            </ion-col>
        </ion-row>
        <ion-row>
            <ion-col>
                <ion-list>
                    <ion-item *ngFor="let ig of loadedRecipe.ingredients">
                        {{ ig }}
                    </ion-item>
                </ion-list>
            </ion-col>
        </ion-row>
    </ion-grid>
</ion-content>

The issue seems to be that loadedRecipe is currently undefined.

Here is the controller TypeScript code:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { RecipesService } from '../recipes.service';

import { Recipe } from '../recipe.model';

@Component({
  selector: 'app-recipe-detail',
  templateUrl: './recipe-detail.page.html',
  styleUrls: ['./recipe-detail.page.scss'],
})
export class RecipeDetailPage implements OnInit {

  loadedRecipe: Recipe;

  constructor(
    private activatedRoute: ActivatedRoute,
    private recipesService: RecipesService
  ) {}

  ngOnInit() {
    console.log(this.activatedRoute.paramMap);
    this.activatedRoute.paramMap.subscribe(paramMap => {
        if (!paramMap.has('recipeId')) {
            // redirect because we don't have the necessary ID
            return;
        }

        console.log(paramMap);
        const recipeId = paramMap.get('recipeId');
        this.loadedRecipe = this.recipesService.getRecipe(recipeId);
    });
  }

}

App-routing module:

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: '', redirectTo: 'recipes', pathMatch: 'full' },
  {
    path: 'recipes',
    children: [
    {
      path: '',
      loadChildren: './recipes/recipes.module#RecipesPageModule'
    },
    {
      path: ':recipeId',
      loadChildren: './recipes/recipe-detail/recipe-detail.module#RecipeDetailPageModule'
    }
    ],
  }
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

List controller recipes.page.ts:

import { Component, OnInit } from '@angular/core';
import { RecipesService } from './recipes.service';
import { Recipe } from './recipe.model';

@Component({
  selector: 'app-recipes',
  templateUrl: './recipes.page.html',
  styleUrls: ['./recipes.page.scss'],
})
export class RecipesPage implements OnInit {

  recipes: Recipe[];


  constructor(private recipesService: RecipesService) { }

  ngOnInit() {
    this.recipes = this.recipesService.getAllRecipes();
  }

}

I suspect there might be an issue with the activated route, but as I am new to debugging web applications, any guidance or tips would be greatly appreciated.

Answer №1

Following Nicholas K's guidance is a step in the right direction. To provide further clarification, here is an example:

app-routing.module.ts

 import { NgModule } from '@angular/core';
 import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

 const routes: Routes = [
   { path: '', redirectTo: 'recipes', pathMatch: 'full' },
   { path: 'recipes', loadChildren: './recipes/recipes.module#RecipesPageModule' },
   { path: 'recipe-detail/:id', loadChildren: './recipe-detail/recipe-detail.module#RecipeDetailPageModule' },
 ];

 @NgModule({
   imports: [
     RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
   ],
   exports: [RouterModule]
 })
 export class AppRoutingModule { }

In recipe-detail.page.ts, as mentioned by Nicholas K, you can access the parameters in the activated route like so:

 ngOnInit() {
   this.id = this.route.snapshot.paramMap.get("id");
   if (this.id != null) {
     console.log('id: ' + this.id);
   }
 }

To navigate from the recipe page to the detail page, you can do it this way (alternatively, you could use routerLink instead of the click event to navigate):

recipes.page.html

 <ion-content>
   <ion-list>
     <ion-item *ngFor="let recipe of recipes" (click)="routeToRecipeDetail(recipe.id)">
       {{recipe.name}}
     </ion-item>
   </ion-list>
 </ion-content>

recipes.page.ts

 import { Component, OnInit } from '@angular/core';
 import { Router } from '@angular/router';

 @Component({
   selector: 'app-recipes',
   templateUrl: './recipes.page.html',
   styleUrls: ['./recipes.page.scss'],
 })
 export class RecipesPage implements OnInit {

   recipes = [
     { id: 1, name: 'pizza' },
     { id: 2, name: 'hamburgers' },
     { id: 3, name: 'salad' }
   ]

   constructor(private router: Router) { }

   ngOnInit() {
   }

   routeToRecipeDetail(id: number) {
     this.router.navigateByUrl('/recipe-detail/' + id);
   }

 }

I have set up a github repository here for your reference. I hope this explanation helps.

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

Unable to connect to the directive even after adding it as an input

In the error message below, it seems that suggestion 1 might be applicable to my situation. My Angular component has a GcUser input, but I have confirmed that it is part of the module (both the component behind the HTML and the user-detail component import ...

Just starting out with TypeScript and running into the error: "Cannot assign type 'null' to type 'User[]'"

Why is TypeScript giving me an error message here? const dispatch = useAppDispatch(); useEffect(() => { onAuthStateChanged(auth, (user) => { dispatch(getUser(user)); }); }, [dispatch]); Error: Argument of type 'User | nul ...

Having trouble installing the Angular/CLI on macOS Mojave due to a node-pre-gyp error?

I recently formatted my iMac and deleted all files on the hard drive. However, upon installing Angular CLI 7, I encountered an error log message in the terminal console. Environment macOS: Mojave 10.14.2 node: v10.15 npm: 6.4.1 Console Error miguels- ...

Obtain an error response from a REST API by utilizing Angular 2

Client.service.ts: add(client: Client): Observable<Client> { return this.authHttp.post(this.URI, client) .map((res) => res.json() //...errors if any ,(message)=>message.json()); Client.add.componement.ts: this.clientS ...

Cypress symbolizes the logical OR condition within a repeating loop

I am currently facing a challenge with testing the input values of a table. I am struggling to represent the OR condition and skipping a specific cell within the table. The table is cyclic in nature, where all values are positive except for one cell that a ...

The entire space should be filled with the background

My goal is to achieve the following while addressing some current issues: The background is currently limited to affecting only the container. I want it to span the entire area. There needs to be space between the cards and padding inside them. https://i ...

Is it feasible to conditionally set a function parameter as optional?

type TestType<A> = [A] extends [never] ? void : A class Singleton<T, A> { private ClassRef: (new (...args: A[]) => T) private args: TestType<A> private _instance?: T constructor(ClassRef: (new (...args: A[]) => T), ...

Viewability of external values in angular designs

Currently, I am facing an issue where multiple modules have duplicated options within the class field: ... options = ['opt1','opt1'] ... To solve this problem, I want to move the duplicated options to a constants module and then im ...

Guide on categorizing MUI icon types

My current code snippet is as follows: type MenuItem = { key: string; order: number; text: string; icon: typeof SvgIcon; }; However, when I attempt to use it in my JSX like this: <List> {MENU.map((menuItem: MenuItem) => ( ...

When the back button is clicked, the Ionic Angular application will navigate to the login screen

Currently, I am in the process of developing an ionic app using Angular and have encountered a problem concerning the android device's back button. When installing the app from Android Studio, the app minimize function (cordova-plugin-appminimize) wo ...

Combining divs with identical values in Angular

I am working on creating my very own custom Calendar. Take a look at the full example of my component here I need help figuring out how to combine week divs that share the same value {{day.weekNumber}} so that there is only one div for each shared value, ...

Button is not responding to the Ionic [clear] property

I attempted to create a transparent button using Ionic's clear attribute as suggested in the documentation. Despite following the instructions, it doesn't seem to work for me. Can you help me identify what I might be doing incorrectly? <butto ...

Return attention to the original content of the page once the success banner at the top has been closed

I am working on a React application with multiple pages that all use a shared banner component. After performing an action on the screen, a success or error message appears at the top in the banner. The issue I'm facing is that when the user dismiss ...

Erase the destination pin on Google Maps

I am currently working on a project that involves displaying hit markers on google maps along with a route from start to finish. Although I have successfully displayed the route, I encountered an issue where both the origin and destination have identical ...

Leveraging Snowflake as a Data Type within Mongoose Schema

Context: Discord.js utilizes Snowflakes to distinguish between various items such as messages, members, and guilds. In my current situation, I am employing snowflakes as distinct identifiers for members within the guild, serving as the primary key in my Mo ...

The command "tsc" was not found in this bash session

Currently, I am using a MAC and attempting to set up TypeScript. I followed the installation process by running sudo npm install -g typescript and received the following output: Password: /Users/<myuserid>/node/bin/tsc -> /Users/<myuserid& ...

Performance of Angular4 UI decreases with a large amount of data objects

https://i.sstatic.net/PdmFk.jpg The table above displays an array of objects, typically containing 50-60 items. As the item count increases, elements like transition animations and click events become slower. However, I have observed that when filtering t ...

The issue with converting a string into an object in Typescript

I am having trouble converting the JSON response from the websocket server to a TypeScript object. I've been trying to debug it but can't seem to find where the error lies. Can anyone assist me in resolving this issue? Below is the code snippet ...

Exploring the Power of Dynamic XML in Your Angular 4/5 Application

If example.com is an active angular 4 application with existing routes such as /product and /category, how could I create a route like /products.XML or /category.xml to display dynamic XML content for each. ...

Ways to attach an event listener to a useRef hook within a useEffect hook

As I work on creating a custom hook, I am faced with the task of adding an event listener to a ref. However, I am uncertain about how to properly handle cleaning up the event listener since both listRef and listRef.current may potentially be null: const ...