Satish

Lazy Loading in Ionic 4

No comments

Lazy Loading sounds like a complicated process, but actually is very straight forward. It refers to the process of loading chunks of code (such as a component, directive or pipe) when it’s requested not when the app is loading. This is a very framework agnostic take on things, and the finer details here come in the form of NgModules for Ionic apps. NgModules are the way we can organize our app’s pages, and separate them out into different chunks.

We will take a look at how lazy loading can be used to help speed up the load times of your Ionic Angular apps. Also, it doesn’t matter if your app is packaged and downloaded from the store, or a progressive web app (PWA) running off a server, lazy loading can help increase your startup times in both situations.

Lazy Loading in Ionic Angular:

The idea behind Lazy Loading is that we only download the HTML, CSS, and JavaScript that our application needs to render its first route, and then load additional pieces of our application as needed. The great news is that a new Ionic Angular 4.0 app has lazy loading configured by default. Lazy loading is expressed through how the Angular routes are setup:

const routes: Routes = [
  {
    path: '',
    loadChildren: './tabs/tabs.module#TabsPageModule'
  }
];

This is the initial route that is created for you when starting a new Ionic app using the tabs starter template. By specifying a loadChildren string (instead of passing a page class to component), the Angular router will load this file dynamically when the user navigates to the route. This JavaScript also gets split off from the rest of the app into its own bundle.
Now below we have the router setup for the Tab router module:

const routes: Routes = [
  {
    path: 'tabs',
    component: TabsPage,
    children: [
      {
        path: 'tab1',
        children: [
          {
            path: '',
            loadChildren: () =>
              import('../tab1/tab1.module').then(m => m.Tab1PageModule)
          }
        ]
      },
      {
        path: 'tab2',
        children: [
          {
            path: '',
            loadChildren: () =>
              import('../tab2/tab2.module').then(m => m.Tab2PageModule)
          }
        ]
      },
      {
        path: '',
        redirectTo: '/tabs/tab1',
        pathMatch: 'full'
      }
    ]
  },
  {
    path: '',
    redirectTo: '/tabs/tab1',
    pathMatch: 'full'
  }
];

Each tab in this configuration loads its children lazily as well, means all files of Tab2 page are not loaded when the user navigates to the tab2 page.

How to optimize Lazy Loading:

Lazy Loading can help your app load fast, however, if a user navigates to a new page, the assets will still need to be downloaded before the user views the page.

When importing the Router module in the main app module, you can specify a pre-loading strategy to use. There are many options we use :

1. No Pre-Loading: Does not perform any pre-loading of lazily loaded modules. This is the default behavior if no strategy is specified.

2. Pre-load All Modules: After your app loads the initial module, this strategy will preload all the rest of the modules when the network becomes idle. In the Ionic starter templates, we set this option for you automatically.
Now pre-loading Strategy parameter on the options object when setting up the router in app-routing.module.ts :

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

const routes: Routes = [
 {
   path: '',
   loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
 }
 //...
];

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

The preloadAllModules strategy essentially loads the rest of the app in memory after the first route loads. Navigating between pages will now be quick, as all the routes and modules are loaded and ready to go.

3. Simple Pre-Loading:

We will start off by creating a simple strategy that we can use to specify which routes we want to pre-load up front. Using this strategy, we can ensure the most important parts of our app are primed and ready to be navigated to after the first screen loads.

In this Pre-Loading only routes that are lazy (have the loadChildren property) are passed into this strategies for processing.

{
    path: '',
    loadChildren: '../tab2/tab2.module#Tab2PageModule',
    data: {
      preload: true
    },
}

Now create the simple loading class to pre-load all lazy routes.

import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';

export class SimpleLoadingStrategy implements PreloadingStrategy {
  preload(route: Route, load: Function): Observable<any> {
    if (route.data && route.data.preload) {
      return load();
    }
    return of(null);
  }
}

Now, go into app-routing.module.ts and pass  SimpleLoadingStrategy in the options. Also, since the custom strategy is a service, pass it into the providers collection as well:

@NgModule({
    providers: [SimpleLoadingStrategy],
    imports: [
      RouterModule.forRoot(routes, { preloadingStrategy: SimpleLoadingStrategy })
    ],
    exports: [RouterModule]
})

Now, any routes with preload set to true will be pre-loaded and ready to use after the app initially loads.

SatishLazy Loading in Ionic 4
read more

What’s New Features Introduced In Ionic 4

No comments

Ionic is one of the best frameworks in the market, It’s open source SDK for developing the Hybrid Mobile Application. There are basically three components such as:

1. A Sass-based UI structure that is specially optimized for mobile UIs.
2. An Angular platform that is helpful in quick scalable app creation.
3. A compiler (Cordova or PhoneGap) or wrapper that is utilized for developing native apps using CSS, JavaScript, and HTML.

New Components Introduced In Ionic 4

Components for the Web:

Web Component are a set of web platform APIs allowing you to create custom, reusable, encapsulated HTML tags to use in web pages.

It is the most significant change as they moved to a web component for each component. Web components are nothing but a set of web platform APIs that can let the developer create reusable, new, or custom encapsulated HTML tags that can use in web application and pages.

Web Components are based on the following specifications:
  • Custom Elements: defines the bases and the fundamentals to design and use new types of DOM elements.
  • Shadow DOM: defines how to use encapsulated styles and markup within a web component.
  • HTML imports: defines how to include and reuse the HTML document in another HTML document.
  • HTML Template: defines how to declare code fragments that will not be used while the page is loading, but could be later instantiated at runtime.

Capacitor:

Capacitor is a cross-platform API and code execution layer that makes it easy to call Native SDKs from web code and to write custom Native plugins required by the app.It also consists of PWA support to enable the developer to write one app and then launch it to the app store.

Stencil:

This new creation of the Ionic team is a web component compiler that is useful for building standards-compliant with web servers. This also uses additional APIs such as TypeScript, JSX, async, and Virtual DOM, which works best for progressive web apps (PWA).

Ion-backdrop:

They are full-screen components which overlay other components.These are placed on top of the other contents, as this way it is able to dismiss another component.

ion-picker:

A Picker displays a row of buttons and columns on top of the app’s content, and at the bottom of the viewport.
> Picker-column
> Picker controller

ion-Ripple Effect:

The ripple effect component adds the Material Design ink ripple interaction effect. It is designed to be efficient, noninvasive, and usable without adding any extra DOM to your elements. It works without javascript degrades to easier CSS-Only implementation.

ion-Route:

It will pick up a component and will render it browser URL gets matched with URL property.

ion-Searchbar:

This includes a text field which is useful for searching from a huge collection. Here, the team of Ionic has added nine bar styles, and out of them all, v4 appears to be the best.

ion-skeleton-text:

Skeleton Text is for rendering placeholder content. It will render a gray block at the specified width.

 

ion-select Popover:

This mainly is a dialogue appearing on top of the current page, and it is used for the overflow actions that do not fit well in the navigation bar.

Ionicons 4.0:

Premium designed icons for use in web, iOS, Android, and desktop apps. Support for SVG and web font now available and distributed as web components with drastically reduced sizes, and brand new icon forms reflecting the latest iOS and Material Design styles.

Tappable Items:

To list items, we were used <button> in v3 but in v4 has the tappable attribute for an <ion-item>.

<ion-item tappable (click)="writeSomething()">

Your Button Item

</ion-item>

CSS Variables:

This is the exclusive feature of Ionic that is going to modernise the whole look of your application making some slight changes in a few variables without even using the build tools.

Color Changes:

The Ionic team has changed the earlier default color and it now has a new default color.

ion-reorder:

Reorder allows items to be dragged to change its order horizontally. It can be used within an ion-reorder-group to provide a visual drag and drop interface.

Lazy Loading:

It is basically a design pattern in the ionic framework which is used to distinguish initialization of the components until it is required. This will help to improve the performance of the app and decrease the load time of the app by dividing it into various bundles and loading the app when asked for.

Ion-show-when:

It shows child content when a query evaluates to true. It can watch for platform changes, mode changes, CSS media queries, and device orientation.

Ionic Native 5:

Ionic Native 5 brings the app development project to the fully framework agnostic status. where our components work with either framework or without a framework. Ionic native 5 requires Angular 5 for those choosing to use injectables/providers.

Changelogs in Native 5:

Changelogs is basically shipped with three bundles, i.e.
>  Angular (5.x+) providers
>  ES6 modules
>  AngularJS support
The bundle releases and ES6 will feature static classes for plugins. Ionic developers who use Angular choose between using the injectables, or can import & use ES6 plugins statically.

SatishWhat’s New Features Introduced In Ionic 4
read more

How to use FTP in Ionic 4

No comments

FTP (File Transfer Protocol)

File Transfer Protocol (FTP) is a standard Internet protocol for transmitting files between computers on the Internet over TCP/IP connections. FTP is a client-server protocol where a client will ask for a file, and a local or remote server will provide it.

How FTP works

FTP is a client-server protocol that relies on two communications channels between client and server: a command channel for controlling the conversation and a data channel for transmitting file content. Clients initiate conversations with servers by requesting to download a file. Using FTP, a client can upload, download, delete, rename, move and copy files on a server. A user typically needs to log on to the FTP server, although some servers make some or all of their content available without login, known as anonymous FTP.

cordova-plugin-ftp

This cordova plugin is created to use ftp (client) in web/js.

Support both iOS and Android platform now.

You can do the following things:

  • List a directory
  • Create a directory
  • Delete a directory (must be empty)
  • Delete a file
  • Download a file (with percent info)
  • Upload a file (with percent info)
  • Cancel upload/download

Installation

$ionic cordova plugin add cordova-plugin-ftp
$npm install @ionic-native/ftp

Dependency:

  • For iOS, the plugin depends on CFNetwork.framework, which has been added to plugin.xml (and cordova prepare will add it to platform project), so you don’t need to do anything.
  • But for Android, it depends on com.android.support:support-v4:23.2.0, which should be added to your platform project by hand.

Usage

How to connect FTP:

For better use of FTP connect once to server means connect to one ftp server.

Just need to init the connection once. If success, you can do any ftp actions later.

connect(hostname, username, password)

import { FTP } from '@ionic-native/ftp/ngx';


constructor(private ftp: FTP) { }

...


this.ftp.connect('ftp_host', 'ftp_user', 'ftp_password')
  .then((res: any) => console.log('Login successful', res))
  .catch((error: any) => console.error(error));
Param Details
hostname The ftp server url. Like ip without protocol prefix, e.g. “192.168.1.1”. Use only the Host name or ip-address
username The ftp login username. If it and password are all blank/undefined, the default username “anonymous” is used.
password The ftp login password. If it and username are all blank/undefined, the default password “anonymous@” is used.

Returns: Promise<any> The success callback. Notice: For iOS, if triggered, means init success, but NOT means the later action, e.g. ls… download will success!

How to upload a File:

Upload one local file to the ftp server after connect the ftp server.

this.ftp.upload(localFile, remoteFile).subscribe(
(result) => {
     console.log(result);
} , (error) => {
     console.log(error);
});
Param Details
localFile The file (with full path) you want to upload. e.g. “/local/path/localFile”.
remoteFile The file (with full path) you want to located on the ftp server. e.g. “/123/newDir/remoteFile”.

Returns:Observable<any> Returns an observable. It will be triggered many times according the file’s size. The arg 00.1xx0.2xx … 1 means the upload percent. When it reach 1, means success.

List files:

List files (with info of nametypelinksizemodifiedDate) under one directory on the ftp server. You can get one file’s name using fileList[x].name (x is the location in array).

this.ftp.ls(path);

Param Details
path The path on the ftp server. e.g. “/adf/123/”.

Returns: Promise<any> Returns a promise

Create & Delete directory:

1. mkdir(path)

Create one directory on the ftp server.

Param Details
path The path on the ftp server. e.g. “/adf/123/”.

Returns: Promise<any> Returns a promise

2. rmdir(path)

Delete one directory on the ftp server.

Tip: As many ftp server could not rm dir when it’s not empty, so rm all files under the dir at first is recommended.

Param Details
path The file (with full path) you want to delete. e.g. “/123/newDir/myFile”.

Returns: Promise<any> Returns a promise

3. rm(file)

Delete one file on the ftp server.

Param Details
file The file (with full path) you want to delete. e.g. “/123/newDir/myFile”.

Returns: Promise<any> Returns a promise

How to download a File:

Download one remote file on the ftp server to local path.

this.ftp.download(localFile, remoteFile).subscribe(
(result) => {
     console.log(result);
} , (error) => {
     console.log(error);
});
Param Details
localFile The file (with full path) you want to upload. e.g. “/local/path/localFile”.
remoteFile The file (with full path) you want to located on the ftp server. e.g. “/123/newDir/remoteFile”.

Returns: Observable<any> Returns an observable. It will be triggered many times according the file’s size. The arg 00.1xx0.2xx … 1 means the upload percent. When it reach 1, means success.

cancel()

Cancel all requests. Always success.

Returns: Promise<any> Returns a promise

disconnect()

Disconnect from ftp server.

Returns: Promise<any> Returns a promise

SatishHow to use FTP in Ionic 4
read more

How to use ion-skeleton-text in Ionic 4

No comments

ion-skeleton-text

Skeleton Text is a component for rendering placeholder content. The element will render a gray block at the specified width.

Skeleton screens… You might think they sound a little scary and or that they’re hard to implement, but what if I told you that they are actually quite simple to make. Once added to your app, skeleton screens become an awesome feature to make your app feel incredibly fast.When building an app, you’re always making sure that you are doing everything correctly from a technical perspective to ensure great performance. But another, often ignored part of performance is called perceived performance. Perceived performance is how fast an action appears to happen to the user. Skeleton screens are a great way to improve the perceived performance of your app, when combined with traditional optimizations (lazy loading, code splitting, etc).

Let’s dive a little deeper into what skeleton screens are, why they are better than traditional loading spinners, and how Ionic makes it easy to use them!

Facebook is  on of the Skeleton  example. They make heavy use of skeleton screens in their native app and web app. They use a similar implementation to Medium, rendering a Skeleton Screen where content will eventually be:

 

 

One problem with that is the more people you compel to give you their time, the harder it becomes for your system to handle all that traffic.

But there is always something extra you can do to shorten the time from app start to app use for your user even if it’s just perceived as being shorter.

Let’s see the all skeleton we use :

LET THERE BE CODE

Let’s create a blank Ionic project and check a cool new feature in Ionic 4 – ion-skeleton-text.

> ionic start ion-skeleton-text blank

Let’s now go into the home.page.html file and add the content

<!-- home.page.html -->
<ion-content>
  <ion-list>
    <ion-item *ngFor="let item of items">
      {{ item }}
    </ion-item>
  </ion-list>
</ion-content>

We also need some content which we will display with some delay

// home.page.ts
export class HomePage implements OnInit {
  items: Array<string>;
  constructor() {}

  ngOnInit(): void {
    setTimeout(() => {
      this.items = [
        'Berlin',
        'Buenos Aires',
        'Madrid',
        'New York',
        'Paris',
        'Sydney',
        'Tokyo'
      ];
    }, 2500);
  }
}

If you now execute

> ionic serve

you will see something like this

                                                No loading indication

ADDING A LOADING SCREEN

In order to let the user know that something is going on in the background, we could add a loading indicator which we would remove once the data has been loaded.

// home.page.html
export class HomePage implements OnInit {
  items: Array<string>;
  constructor(private loadingController: LoadingController) {}

  ngOnInit(): void {
    this.loadData();
  }

  async loadData(): Promise<void> {
    const loading = await this.loadingController.create({
      message: 'Loading cities...'
    });

    await loading.present();

    setTimeout(() => {
      this.items = [
        'Berlin',
        'Buenos Aires',
        'Madrid',
        'New York',
        'Paris',
        'Sydney',
        'Tokyo'
      ];

      loading.dismiss();
    }, 2500);
  }
}

I won’t go into the fact that displaying a loading screen should be handled separately because that’s not the point of this post but I know you would never push code like this 😉

Now if we save and check out our browser again we will see a nice loading screen.

                                                Loading screen

LET’S MAKE IT A LITTLE BETTER

One thing that we know about loading screens is that we don’t really like them. Loading screens on games, apps or anywhere else is something that starts to annoy us quite quickly so we have to keep them as short as possible or remove them completely.

We can try to trick people into believing that the app is already in the process of displaying some content when in fact it’s still waiting for the server to respond. In some cases, it’s just enough to let your users feel like the app is working to make them happy.

ION-SKELETON-TEXT IS THE ANSWER

ion-skeleton-text is a new UI component which displays a placeholder content instead of the true one.

Implementing it is very straight-forward as you will see soon. Let’s dive right into it.

<!-- home.page.html -->
<ion-content>
  <ion-list *ngIf="items; else skeleton">
    <ion-item *ngFor="let item of items">
      {{ item }}
    </ion-item>
  </ion-list>
</ion-content>

<ng-template #skeleton>
  <ion-list>
    <ion-item *ngFor="let item of [50, 20, 70, 80, 50]">
      <p [ngStyle]="{ width: item + '%' }">
        <ion-skeleton-text animated></ion-skeleton-text>
      </p>
    </ion-item>
  </ion-list>
</ng-template>

What we do here is to simply show the items once they are set (after the 2500 ms) while displaying a few placeholder items in the mean-time.

We also got rid of the loading screen code again in the home.page.ts file to make it look like it was before.

// home.page.ts
export class HomePage implements OnInit {
  items: Array<string>;
  constructor() {}

  ngOnInit(): void {
    this.loadData();
  }

  async loadData(): Promise<void> {
    setTimeout(() => {
      this.items = [
        'Berlin',
        'Buenos Aires',
        'Madrid',
        'New York',
        'Paris',
        'Sydney',
        'Tokyo'
      ];
    }, 2500);
  }
}

Now if you save all you will see something like this:

                                                Skeleton Skeleton text

This looks a lot more dynamic than having just a simple spinner and loading message. If you are displaying complex data you can even take advantage of two other cool Ionic component – ion-avatar and ion-thumbnail.

Let’s create one final skeleton-text item which will represent some more complex data.

<!-- home.page.html -->
<ion-content>
  <ion-list *ngIf="items; else skeleton">
    <ion-item *ngFor="let item of items">
      <ion-thumbnail slot="start">
        <img [src]="item.image" />
      </ion-thumbnail>
      <ion-label>
        <h3>City: {{ item.city }}</h3>
        <p>Country: {{ item.country }}</p>
        <p>Population: {{ item.population }}</p>
      </ion-label>
    </ion-item>
  </ion-list>
</ion-content>

<ng-template #skeleton>
  <ion-list>
    <ion-item *ngFor="let item of [1, 2, 3, 4, 5]">
      <ion-thumbnail slot="start">
        <ion-skeleton-text animated></ion-skeleton-text>
      </ion-thumbnail>
      <ion-label>
        <h3>
          <ion-skeleton-text animated style="width: 50%"></ion-skeleton-text>
        </h3>
        <p>
          <ion-skeleton-text animated style="width: 80%"></ion-skeleton-text>
        </p>
        <p>
          <ion-skeleton-text animated style="width: 60%"></ion-skeleton-text>
        </p>
      </ion-label>
    </ion-item>
  </ion-list>
</ng-template>

The typescript code has change also a little:

export class HomePage implements OnInit {
  items: Array<any>;
  constructor() {}

  ngOnInit(): void {
    this.loadData();
  }

  async loadData(): Promise<void> {
    setTimeout(() => {
      this.items = [
        { city: 'Berlin', country: 'Germany', population: '3.5 million', image: '...' },
        { city: 'Buenos Aires', country: 'Argentina', population: '15 million', image: '...' },
        { city: 'Madrid', country: 'Spain', population: '3.3 million', image: '...' },
        { city: 'New York', country: 'USA', population: '19.5 million', image: '...' },
        { city: 'Paris', country: 'France', population: '2.2 million', image: '...' },
        { city: 'Sydney', country: 'Australia', population: '5.4 million', image: '...' },
        { city: 'Tokyo', country: 'Japan', population: '9.2 million', image: '...' }
      ];
    }, 2500);
  }
}

The final result looks now like this:

 

A more complex example

Now that’s pretty, isn’t it?

The ion-skeleton-text UI component can add a little twist to your app and give the user something shiny to look at while your app does all the heavy lifting. It will keep them focused on something until the final content loads fully and you are able to display it. Giving the user the feeling that the app is running instead of waiting will make them come back and will give you more users to serve.

SatishHow to use ion-skeleton-text in Ionic 4
read more

Laravel Validation

No comments

Validation is one of the fundamental elements of any application. Laravel Framework provides several approaches to validate incoming user data. ValidatesRequests Trait is used by Laravel’s Base Controller to validate incoming HTTP requests. It also supports a variety of powerful rules.

# Adding Validations

To add validation logic to check user data, we use the validate method provided by the Illuminate\Http\Request object. This is because we can fetch user input data with the Request class.
The code continues execution normally if the validation rules pass. But if the validation fails, an exception is thrown and the user is informed with an automatic error message. For a better perspective, let us write some validation rules:

# controller

   public function store(Request $request)
{
$request->validate([
'title' => 'required|unique:posts|max:255',
'category' => 'required',
]);
}

# Validating Nested Parameters

In case HTTP layout or request comprise of nested parameters, we can specify them with a “.“(dot) operator in the validation rules like:

# controller
public function store(Request $request)
{
$request->validate([
'title' => 'required|max:255',
'author.name' => 'required',
'author.contact' => 'required',
]);
}

# Displaying Validation Errors

The next step is to determine a way to handle exceptions thrown on validation failures. As we discussed earlier, Laravel automatically sends an error message. It also redirects the user to the previous location where the error is supposed to be rectified. Additionally, Laravel also flashes these messages on sessions so that we can have global access to them amidst controllers and layout views.

This eliminates the need to explicitly bind the error messages to views or routes. Laravel keeps a check on session error data and automatically binds them to views if available.

Let us see how we can utilize these session error messages to display to our users through views:

# blade

 

@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif

we have a new validation option: image dimensions for image uploads. The validation rule is called dimensions, and you can pass the following parameters to it:

min_width: Images narrower than this pixel width will be rejected
max_width: Images wider than this pixel width will be rejected
min_height: Images shorter than this pixel height will be rejected
max_height: Images taller than this pixel height will be rejected
width: Images not exactly this pixel width will be rejected
height: Images not exactly this pixel height will be rejected
ratio: Images not exactly this ratio (width/height, expressed as “width/height”) will be rejected

You can combine any rules that make sense together. Let’s take a look at a few examples. First, let’s set up our base install.

// routes file
Route::get('/', function () {
return view('form');
});


Route::post('/', 'ImageController@postImage');

//form.blade.php

<form method="POST" enctype="multipart/form-data">
<input type="file" name="avatar">
<input type="submit">
</form>

Now, let’s make our ImageController and take a look at a few sample validations.

// ImageController
public function postImage(Request $request)
{
$this->validate($request, [
'avatar' => 'dimensions:min_width=250,min_height=500'
]);

// or…

$this->validate($request, [
'avatar' => 'dimensions:min_width=500,max_width=1500'
]);

// or…

$this->validate($request, [
'avatar' => 'dimensions:width=100,height=100'
]);

// or…

// Ensures that the width of the image is 1.5x the height
$this->validate($request, [
'avatar' => 'dimensions:ratio=3/2'
]);
}

SatishLaravel Validation
read more