Ionic 5 and Angular 8: Create a Welcome Page with Tabs Home Pages.
Wall Script
MailxEngine
Sunday, August 18, 2019

Ionic 5 and Angular 8: Create a Welcome Page with Tabs Home Pages.

I received lots of tutorial requests from my readers in that most of them asked me, how to use Ionic 5 to create a welcome page with login and signup pages. Ionic updated there code base with latest Angular 8 features. Now we can implement the routes and guards pretty easy way. Ionic is recommending to use Capacitor to generate iOS and Android. This post will explain to you how to design an Ionic project structure with social project related pages like messages, feed, notifications, etc. Finally converting this web Ionic project to iOS and Android applications.

Ionic 5 and Angular 8:Create a Welcome Page with Login and Logout.


Live Demo

Prerequisites
You need to have the following software installed:
  • Node 12+
  • Ionic 5+

Video Tutorial


Create Ionic Project
Generate an Ionic project with tabs feature.
$ionic start mango tabs

Run the Project
Project server will run at 8100 port.
$ionic serve

Working with New Project Structure
Create folders like Pages, Components, and Services.
Ionic 5 and Angular 8 Create project structure

Home Container
All of the authenticated pages under this container routes. For more inforamtion read Angular Routing using Route Guards
mango$ ionic generate page home
> ng generate page home
CREATE src/app/home/home.module.ts (533 bytes)
CREATE src/app/home/home.page.scss (0 bytes)
CREATE src/app/home/home.page.html (123 bytes)
CREATE src/app/home/home.page.spec.ts (677 bytes)
CREATE src/app/home/home.page.ts (248 bytes)
UPDATE src/app/app-routing.module.ts (488 bytes)
[OK] Generated page!

Index Container
Unauthorized pages under this component.
mango$ ionic generate page index
> ng generate page index
CREATE src/app/index/index.module.ts (538 bytes)
CREATE src/app/index/index.page.scss (0 bytes)
CREATE src/app/index/index.page.html (124 bytes)
CREATE src/app/index/index.page.spec.ts (684 bytes)
CREATE src/app/index/index.page.ts (252 bytes)
UPDATE src/app/app-routing.module.ts (563 bytes)
[OK] Generated page!

Generate Unauthenticated Pages
Use Ionic command to generate unauthenticated pages like login, signup, welcome and forgot under the pages directory.
mango$ ionic generate page pages/welcome
> ng generate page pages/welcome
CREATE src/app/pages/welcome/welcome.module.ts (548 bytes)
CREATE src/app/pages/welcome/welcome.page.scss (0 bytes)
CREATE src/app/pages/welcome/welcome.page.html (126 bytes)
CREATE src/app/pages/welcome/welcome.page.spec.ts (698 bytes)
CREATE src/app/pages/welcome/welcome.page.ts (260 bytes)
UPDATE src/app/app-routing.module.ts (652 bytes)
[OK] Generated page!
mango$ ionic generate page pages/login
> ng generate page pages/login
CREATE src/app/pages/login/login.module.ts (538 bytes)
CREATE src/app/pages/login/login.page.scss (0 bytes)
CREATE src/app/pages/login/login.page.html (124 bytes)
CREATE src/app/pages/login/login.page.spec.ts (684 bytes)
CREATE src/app/pages/login/login.page.ts (252 bytes)
UPDATE src/app/app-routing.module.ts (733 bytes)
[OK] Generated page!
mango$ ionic generate page pages/signup
> ng generate page pages/signup
CREATE src/app/pages/signup/signup.module.ts (543 bytes)
CREATE src/app/pages/signup/signup.page.scss (0 bytes)
CREATE src/app/pages/signup/signup.page.html (125 bytes)
CREATE src/app/pages/signup/signup.page.spec.ts (691 bytes)
CREATE src/app/pages/signup/signup.page.ts (256 bytes)
UPDATE src/app/app-routing.module.ts (818 bytes)
[OK] Generated page!

Generate Authenticated Pages
Same way generate all of the authenticated pages like feed, messages, notifications and setttings. Later we are going to apply route guards to protect these with the user authentication.
mango$ ionic generate page pages/feed
> ng generate page pages/feed
CREATE src/app/pages/feed/feed.module.ts (533 bytes)
CREATE src/app/pages/feed/feed.page.scss (0 bytes)
CREATE src/app/pages/feed/feed.page.html (123 bytes)
CREATE src/app/pages/feed/feed.page.spec.ts (677 bytes)
CREATE src/app/pages/feed/feed.page.ts (248 bytes)
UPDATE src/app/app-routing.module.ts (895 bytes)
[OK] Generated page!
mango$ ionic generate page pages/messages
> ng generate page pages/messages
CREATE src/app/pages/messages/messages.module.ts (553 bytes)
CREATE src/app/pages/messages/messages.page.scss (0 bytes)
CREATE src/app/pages/messages/messages.page.html (127 bytes)
CREATE src/app/pages/messages/messages.page.spec.ts (705 bytes)
CREATE src/app/pages/messages/messages.page.ts (264 bytes)
UPDATE src/app/app-routing.module.ts (988 bytes)
[OK] Generated page!
mango$ ionic generate page pages/notifications
> ng generate page pages/notifications
CREATE src/app/pages/notifications/notifications.module.ts (578 bytes)
CREATE src/app/pages/notifications/notifications.page.scss (0 bytes)
CREATE src/app/pages/notifications/notifications.page.html (132 bytes)
CREATE src/app/pages/notifications/notifications.page.spec.ts (740 bytes)
CREATE src/app/pages/notifications/notifications.page.ts (284 bytes)
UPDATE src/app/app-routing.module.ts (1101 bytes)
[OK] Generated page!
mango$ ionic generate page pages/settings
> ng generate page pages/settings
CREATE src/app/pages/settings/settings.module.ts (553 bytes)
CREATE src/app/pages/settings/settings.page.scss (0 bytes)
CREATE src/app/pages/settings/settings.page.html (127 bytes)
CREATE src/app/pages/settings/settings.page.spec.ts (705 bytes)
CREATE src/app/pages/settings/settings.page.ts (264 bytes)
UPDATE src/app/app-routing.module.ts (1194 bytes)
[OK] Generated page!

Lazy Routing & Navigation
You have to connect all of the pages with Index and Home containers.

index.router.ts
Create a router class and import unauthenticated pages here.
import;
import { RouterModule, Routes } from '@angular/router';
import { IndexPage } from './index.page';

const routes: Routes = [
{
path: '',
component: IndexPage,
children: [
{
path: '',
loadChildren: () =>
import('../pages/welcome/welcome.module').then(
m => m.WelcomePageModule
)
},
{
path: 'login',
loadChildren: () =>
import('../pages/login/login.module').then(m => m.LoginPageModule)
},
{
path: 'signup',
loadChildren: () =>
import('../pages/signup/signup.module').then(m => m.SignupPageModule)
}
]
}
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class IndexRouter {}

home.router.ts
Here import the user authenticated pages.
import;
import { RouterModule, Routes } from '@angular/router';
import { HomePage } from './home.page';

const routes: Routes = [
{
path: 'home',
component: HomePage,
children: [
{
path: 'feed',
loadChildren: () =>
import('../pages/feed/feed.module').then(m => m.FeedPageModule)
},
{
path: 'messages',
loadChildren: () =>
import('../pages/messages/messages.module').then(
m => m.MessagesPageModule
)
},
{
path: 'notifications',
loadChildren: () =>
import('../pages/notifications/notifications.module').then(
m => m.NotificationsPageModule
)
},
{
path: 'settings',
loadChildren: () =>
import('../pages/settings/settings.module').then(
m => m.SettingsPageModule
)
}
]
}
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class HomeRouter {}

index.module.ts
Now remove the existing routes and import the IndexRouter.
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { IndexPage } from './index.page';
import { IndexRouter } from './index.router';

@NgModule({
imports: [CommonModule, FormsModule, IonicModule, IndexRouter],
declarations: [IndexPage]
})
export class IndexPageModule {}

home.module.ts
Follow the same and import HomeRouter.
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { HomePage } from './home.page';
import { HomeRouter } from './home.router';

@NgModule({
imports: [CommonModule, FormsModule, IonicModule, HomeRouter],
declarations: [HomePage]
})
export class HomePageModule {}

app-routing.module.ts
Drop the default tabs modules and connect with Index and Home containers.
import;
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [
{
path: '',
loadChildren: () =>
import('./index/index.module').then(m => m.IndexPageModule)
},
{
path: '',
loadChildren: () => import('./home/home.module').then(m => m.HomePageModule)
}
];
@NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule {}


index.page.html
Modify the Index container HTML to load pages using router-outlet tag.
<ion-content>
<router-outlet></router-outlet>
</ion-content>

home.page.html
Load the pages with ion-tabes. Find the proper icons from Ionic icons
<ion-tabs>

<ion-tab-bar slot="bottom" color="dark">
<ion-tab-button tab="feed">
<ion-icon name="paper"></ion-icon>
<ion-label>Feed</ion-label>
</ion-tab-button>

<ion-tab-button tab="messages">
<ion-icon name="send"></ion-icon>
<ion-label>Messages</ion-label>
</ion-tab-button>

<ion-tab-button tab="notifications">
<ion-icon name="notifications"></ion-icon>
<ion-label>Contact</ion-label>
</ion-tab-button>

<ion-tab-button tab="settings">
<ion-icon name="cog"></ion-icon>
<ion-label>Settings</ion-label>
</ion-tab-button>

</ion-tab-bar>
</ion-tabs>

Delete Tabs Folders
We are not going to use these default folder.
Ionic 5 and Angular 8:Create a Welcome Page with Login and Logout.

Generate Components Module
In this file import all the child or web components.
/mango$ ionic generate module components

> ng generate module components
CREATE src/app/components/components.module.ts (196 bytes)
[OK] Generated module!

variable.scss
Modify the application SCSS for custom theming. For more understand please watch the video.
:root {
/** primary **/
.......
.......
/** primary end **/
--ion-color-mango: #ffcc66;
--ion-color-mango-rgb: 255,204,102;
--ion-color-mango-contrast: #000000;
--ion-color-mango-contrast-rgb: 0,0,0;
--ion-color-mango-shade: #e0b45a;
--ion-color-mango-tint: #ffd175;

ion-tab-button.tab-selected {
ion-icon, ion-label {
color: var(--ion-color-mango) !important;
--ion-color-base: var(--ion-color-mango) !important;
}
}
}

.ion-color-mango {
--ion-color-base: var(--ion-color-mango);
--ion-color-base-rgb: var(--ion-color-mango-rgb);
--ion-color-contrast: var(--ion-color-mango-contrast);
--ion-color-contrast-rgb: var(--ion-color-mango-contrast-rgb);
--ion-color-shade: var(--ion-color-mango-shade);
--ion-color-tint: var(--ion-color-mango-tint);
}


Working with Child Components

Slides
Generate a component under the components folder. Here you have to design the Welcome page slides.
mango$ ionic generate component components/slides
> ng generate component components/slides
CREATE src/app/components/slides/slides.component.scss (0 bytes)
CREATE src/app/components/slides/slides.component.html (25 bytes)
CREATE src/app/components/slides/slides.component.spec.ts (726 bytes)
CREATE src/app/components/slides/slides.component.ts (268 bytes)
[OK] Generated component!

slides.html
Include the design
<ion-slides pager="true" [options]="slideOpts">
<ion-slide>
<img src="assets/images/logo.png" />
<h2>Welcome to Project</h2>
</ion-slide>
<ion-slide>
<h2>Slide 2 Title</h2>
</ion-slide>
<ion-slide>
<h2>Slide 3 Title<</h2>
</ion-slide>
</ion-slides>


slide.component.ts
Add the slides options for controlling the slides.
import { Component } from '@angular/core';

@Component({
selector: 'app-slides',
templateUrl: './slides.component.html',
styleUrls: ['./slides.component.scss']
})
export class SlidesComponent {
slideOpts = {
speed: 400
};
constructor() {}
}

slides.scss
Enhance the default design with SCSS.
ion-slide {
padding: 160px 20px 160px 20px;
display: block;
img {
width: 100px;
}
h2 {
font-size: 36px;
font-weight: bold;
}
}

Start Button
Create a start button component.
<ion-button expand="block" share="round" color="mango" (click)="navigateToLogin()">Start</ion-button>

start.component.html
Start button with click action to navigating to Login page.
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@Component({
selector: 'app-start-button',
templateUrl: './start-button.component.html',
styleUrls: ['./start-button.component.scss']
})
export class StartButtonComponent implements OnInit {
constructor(private router: Router) {}

ngOnInit() {}

navigateToLogin() {
this.router.navigate(['/login']);
}
}

components.module.ts
Export all the child components here.
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { SlidesComponent } from './slides/slides.component';
import { StartButtonComponent } from './start-button/start-button.component';

@NgModule({
declarations: [SlidesComponent, StartButtonComponent],
exports: [SlidesComponent, StartButtonComponent],
imports: [CommonModule, FormsModule, IonicModule]
})
export class ComponentsModule {}

welcome.module.ts
Import the components module for to import child components.
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { IonicModule } from '@ionic/angular';
import { ComponentsModule } from './../../components/components.module';
import { WelcomePage } from './welcome.page';

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

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

welcome.page.html
Import the child component tags.
<ion-content padding="true">
<app-slides></app-slides>
<app-start-button></app-start-button>
</ion-content>

login.page.html
Design the login form with ionic form elements. Next post will discuss about the API authentication
<ion-header>
<ion-toolbar color="mango">
<ion-title>Login</ion-title>
</ion-toolbar>
</ion-header>

<ion-content padding='true'>
<img src="assets/images/logo.png" class="smallLogo"/>
<h1>Sign In</h1>
<form>
<ion-list>
<ion-item>
<ion-label position="stacked">Username</ion-label>
<ion-input autocomplete="off" type="text"></ion-input>
</ion-item>

<ion-item>
<ion-label position="stacked">Password</ion-label>
<ion-input autocomplete="off" type="password"></ion-input>
</ion-item>

<ion-item lines='none'>
<a routerLink='/signup'>Create Account</a>
</ion-item>
</ion-list>
<ion-button expand="block" share="round" color="success">Login</ion-button>
</form>
</ion-content>

signup.page.html
You will understand more if you watch the video demo
<ion-header>
<ion-toolbar color="mango">
<ion-title>Registration</ion-title>
</ion-toolbar>
</ion-header>

<ion-content padding='true'>
<img src="assets/images/logo.png" class="smallLogo"/>
<h1>Create Account</h1>
<form>
<ion-list>
<ion-item>
<ion-label position="stacked">Email</ion-label>
<ion-input autocomplete="off" type="email"></ion-input>
</ion-item>
<ion-item>
<ion-label position="stacked">Username</ion-label>
<ion-input autocomplete="off" type="text"></ion-input>
</ion-item>

<ion-item>
<ion-label position="stacked">Password</ion-label>
<ion-input autocomplete="off" type="password"></ion-input>
</ion-item>

<ion-item lines='none'>
Already have an account? <a routerLink='/login'>Sign in.</a>
</ion-item>
</ion-list>
<ion-button expand="block" share="round" color="success">Registration</ion-button>
</form>
</ion-content>

Building a Mobile Application
You have to create a production build for generating mobile applications.

Production Build
$ ionic build --prod

Build iOS App
Following commands for executing Xcode build, watch the video tutorial you will understand more.
$ ionic capacitor add ios
$ ionic capacitor open ios

Build Android App
Open Android build using Android SDK
$ ionic capacitor add android
$ ionic capacitor open andriod


Project Updates
If you want to update your project changes.
$ ionic capacitor copy ios
$ ionic capacitor copy ios
web notification

2 comments:

  1. error occurred while running subprocess npm.

    ReplyDelete
  2. hi, thanks for your tutorial. it's clear at all.
    is my firts app with capacitor in android and i get a loit of errors in Android Studio.
    09/10 13:38:50: Launching app
    $ adb push C:\ionic4\mango\android\app\build\outputs\apk\debug\app-debug.apk /data/local/tmp/io.ionic.starter
    com.android.ddmlib.AdbCommandRejectedException: device unauthorized.
    This adb server's $ADB_VENDOR_KEYS is not set
    Try 'adb kill-server' if that seems wrong.
    Otherwise check for a confirmation dialog on your device.
    Error while Installing APK
    can you help me ? please?

    ReplyDelete

Make in India