Search code examples
angularionic-frameworkionic4angular-routingionic7

How can I update this Ionic app to address issues with routing?


I'm currently facing issues with an Ionic application development course that assumes the use of Ionic 4 or 5, while I'm working with version 7. Specifically, I'm encountering problems with routing.

The provided code successfully displays the home page at http://localhost:8101/recipes. However, when attempting to access http://localhost:8101/recipes/r1, only a blank page is shown.

I suspect the version difference might be the cause of the issue. Could you please help me identify the necessary updates or modifications to make this Ionic app work seamlessly with version 7?

Below are snippets of relevant code:

Here is the recipe.model.ts file:

export class Recipe {
    id: string = '';
    title: string = '';
    imageUrl: string = '';
    ingredients: string[] = [];
}

const recipe: Recipe = new Recipe();  

here is the recipes.service.ts file:

import { Injectable } from '@angular/core';
import { Recipe } from './recipe.model';

@Injectable({
  providedIn: 'root'
})
export class RecipesService {

  private recipes: Recipe[] = [
    {
      id:'r1',
      title: 'Scnitzel',
      imageUrl:'https://upload.wikimedia.org/wikipedia/commons/thumb/2/22/Breitenlesau_Krug_Br%C3%A4u_Schnitzel.JPG/220px-Breitenlesau_Krug_Br%C3%A4u_Schnitzel.JPG',
      ingredients: ['French Fries','Pork Meat','Salad']
    },
    {
      id:'r2',
      title: 'Spaghetti',
      imageUrl:'https://upload.wikimedia.org/wikipedia/commons/2/2a/Spaghetti_al_Pomodoro.JPG',
      ingredients: ['Spaghetti','Meat','Tomatoes']
    }
  ];

  constructor() { }

  getAllRecipes(){
    return [...this.recipes];
  }

  getRecipe(recipeId: string){
    return{
      ...this.recipes.find(recipes=>{
        return recipes.id === recipeId;
      })!
      
    }
  }
}

Here is the recipe-detail.page.ts file:

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 = new Recipe();

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

  ngOnInit() {
    this.activatedRoute.paramMap.subscribe(paramMap =>{
      if (!paramMap.has('recipeId')) {
        //redirect
        return;
      }
      const recipeId = paramMap.get('recipeId')!;
            this.loadedRecipe = this.recipesService.getRecipe(recipeId)!;

    });
  }

}

here is the recipe-detail.page.html file:

<ion-header [translucent]="true">
  <ion-toolbar color="primary">
    <ion-title>{{ loadedRecipe.title }}</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-grid no-padding>
    <ion-row>
      <ion-col no-padding>
        <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>

I have tried to look for answers on YouTube but not much luck there either.


Solution

  • Thank you for the stackblitz!

    Explanation.

    <>/recipe-detail/id1

    In the above URL, we are matching recipe-detail to the path definition on the app-routing.ts which is ok

    But if you look at the next section id1 this is going to be our recipe ID, but if we look at the recipe-detail-routing.module.ts we have defined only one route, with path as '' so it will only match for <<basepath>>/recipe-detail but we need to match for <<basepath>>/recipe-detail/:recipeId, so I have added the path :recipeId to the route, so that the ID gets matched and the details are rendered!

    Changes made:

    recipe.page.html - I added the routerLink to navigate to the detail page!

    <ion-list>
      <ion-item *ngFor="let recipe of recipes" [routerLink]="['recipe-detail', recipe.id]">
    <ion-avatar>
    

    recipe-detail-routing.module.ts - We are using receiptId route param, but its not present in the path definition, so I added it!

    const routes: Routes = [
      {
        path: ':recipeId', // <- changed here
        component: RecipeDetailPage
      }
    ];
    

    stackblitz demo