What is wrong with my page transition? Ionic 4 (video)

#1

I used a default ionic 4 starter app with side menu after Ionic 4 was released, so it’s the latest version. Then built a new app from that. I’ve changed nothing really apart from adding content. Bare bone app with just functional stuff added.

Is this how it’s supposed to perform? It behaves like this in browser with ionic:serve and deployed to Android. Forcing iOS has the same white space blinking going on.

Have I forgot to enable something in Ionic 4?

#2

Without seeing the templates, not sure.

#3

Sure, here’s the page:

import { Component, OnInit } from '@angular/core';
import {CalendarModel, CategoryModel} from '../app.models';
import {Events} from '@ionic/angular';
import {ApiService} from '../services/api.service';
import {ActivatedRoute, Router} from '@angular/router';

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

    public calendar: CalendarModel;
    public categories: Array <CategoryModel>;
    public numberOfCategories = 0;
    public loading;

    constructor(public events: Events, public api: ApiService, public route: ActivatedRoute, public router: Router) {

        this.events.subscribe('user:booked', () => {
            this.getCategories();
        });

        this.events.subscribe('user:unbooked', () => {
            this.getCategories();
        });

    }

    ngOnInit() {
        //
    }

    ionViewDidEnter() {
        this.api.getCalendar(this.route.snapshot.paramMap.get('calendar_guid')).then((res: any) => {
            this.calendar = res.calendar;
        });
        this.getCategories();
    }

    async getCategories() {
        this.loading = true;
        return await this.api.getCategoriesForCalendar('planner', this.route.snapshot.paramMap.get('calendar_guid')).then((res: any) => {
            this.loading = false;
            this.numberOfCategories = res.total_count;
            this.categories = res.categories;
        });
    }

    viewCategory(category: CategoryModel) {
        this.router.navigateByUrl('time-category/' + category.guid + '/' + this.calendar.guid);
    }

    doRefresh(event) {
        this.getCategories().then(() => event.target.complete());
    }

}

And here’s the page module:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';

import { IonicModule } from '@ionic/angular';

import { TimeCategoriesPage } from './time-categories.page';

const routes: Routes = [
  {
    path: '',
    component: TimeCategoriesPage
  }
];

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    RouterModule.forChild(routes)
  ],
  declarations: [TimeCategoriesPage]
})
export class TimeCategoriesPageModule {}

And here’s the template:

<ion-header>
    <ion-toolbar color="primary" *ngIf="calendar">
        <ion-buttons slot="start">
            <ion-back-button></ion-back-button>
        </ion-buttons>
        <ion-title>{{ calendar.name }}</ion-title>
    </ion-toolbar>
</ion-header>

<ion-content *ngIf="categories" color="mediumlight">
    
    <ion-card color="white" *ngFor="let category of categories" (click)="viewCategory(category)">

        <img *ngIf="category.image_url" src="{{ category.image_url }}"/>

        <ion-card-header>
            <ion-card-subtitle>{{ category.displayed_interval }} min</ion-card-subtitle>
            <ion-card-title>{{ category.name }}</ion-card-title>
        </ion-card-header>

        <ion-card-content *ngIf="category.description">
            {{ category.description }}
        </ion-card-content>
    </ion-card>

    <ion-row *ngIf="loading">
        <ion-col text-center>
            <ion-spinner></ion-spinner>
        </ion-col>
    </ion-row>

</ion-content>

There is no custom CSS at all (apart from mediumlight in variables.css, I’ve tested without this. Same thing happens)

#4

I see the issue. Your toolbar component has an *ngIf=“calendar” applied to it. This is initially resolved to null, so it is not applied. Once the lifecycle events resolve it, it shows.

Two solutions, use route resolvers to get the data before the page is loaded, or change the ionViewDidEnter to IonViewWillEnter.

#6

Oh right, I remember why I did that it was because of as you said that for example the user variable for a page was null inside the until the page fully loaded. So I lazilly just wrapped that in an ngIf.

Thx for the tip to change to “will enter” instead.