Search code examples
angulartypescriptionic-frameworkangular-router

Router.navigate problems in ionic-angular app


I'm building a simple app in angular 9- ionic 5. I have a list of item in my main page

My HTML code:

<ion-header>
  <ion-toolbar>
    <ion-title>recipes</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-list>
    <app-recipe-item *ngFor="let recipe of recipes" [recipeItem]="recipe">
    </app-recipe-item>

  </ion-list>
</ion-content>

And my TS code:

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

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

  recipes: Recipe[];

  constructor(
    private recipesService: RecipesService
  ) { }

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

  ngOnChanges(changes: SimpleChanges) {
  }

}

When I click on an item of the list I will be routed to the item detail page where I can delete the item

HTML:

<ion-header>
  <ion-toolbar color="primary">
    <ion-button slot="start">
      <ion-back-button defaultHref="/recipes"></ion-back-button>
    </ion-button>
    <ion-title>
      {{ loadedRecipe.title }}
    </ion-title>
    <ion-button slot="primary" (click)="onDeleteRecipe()">
      <ion-icon slot="icon-only" name="trash"></ion-icon>
    </ion-button>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-grid fixed class="ion-no-padding">
    <ion-row>
      <ion-col class="ion-no-padding">
        <ion-img [src]="loadedRecipe.imageUrl"></ion-img>
      </ion-col>
    </ion-row>
    <ion-row>
      <ion-col size="12">
        <h1 class="ion-text-center">{{ loadedRecipe.title}}</h1>
      </ion-col>
    </ion-row>
    <ion-row>
      <ion-col size="12">
        <ion-item *ngFor="let ig of loadedRecipe.ingredients">
          {{ ig }}
        </ion-item>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

TS:

import { RecipesService } from './../recipes.service';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Recipe } from '../recipes.model';
import { AlertController } from '@ionic/angular';
    
@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 recipeService: RecipesService,
    private router: Router,
    private alertCtrl: AlertController
  ) {}

  ngOnInit() {
    this.activatedRoute.paramMap
      .subscribe(paramMap => {
        if (!paramMap.has('recipeId')) {
          // redirect
          this.router.navigate(['/recipes'])
          return;
        } else {
          const recipeId = paramMap.get('recipeId');
          this.loadedRecipe = this.recipeService.getRecipe(recipeId);
        }
      });
  }

  onDeleteRecipe() {
    this.alertCtrl.create({
      header: 'Are yo sure?',
      message: 'Do you want to delete the recipe?',
      buttons: [{
          text: 'Cancel',
          role: 'cancel'
        },
        {
          text: 'Delete',
          handler: () => {
            this.recipeService.deleteRecipe(this.loadedRecipe.id);
            this.router.navigate(['/recipes']);
          }
        }
      ]
    }).then(alertEl => {
      alertEl.present();
    });
  }

}

Now, when I delete an item I get redirected to the parent page with my router.navigate method, but I still have all the item in the list. The method onInit is not fired so I will not recover the updated list of item. When I click on the deleted item I get redirected to an empty page, because I don't have that item anymore. What should I do to not see the deleted item in my main page anymore?


Solution

  • This is happening because of caching in Ionic.

    Code which you want to load every time you can put in ionViewWillEnter method.

    ionViewWillEnter() {
      // code which you want to load every time.
    }
    

    In you RecipesPage change

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

    to

    ionViewWillEnter() {
       this.recipes = this.recipesService.getAllRecepies();
    }