Search code examples
javascriptangulartypescriptangular2-routingangular-routing

How to separate desktop and mobile page and lazy load each page in Angular?


my goal is to separate desktop and mobile page. The reason is that the desktop page UX flow is "scroll to section". Meanwhile, the mobile page UX flow is "navigate to the next section".

The problem:

  1. The desktop user will load mobile page. Same goes for the mobile user.

This is the visual diagram of the current solution:

  1. there is a main page and get-device-type service.
  2. the main page will render the desktop page or the mobile page. enter image description here

What I've tried:

  1. use canLoad for desktop page.

My expectation:

  1. When the desktop user visit path checkout/1, it will load the desktop page.
  2. When the mobile user visit path checkout/1, it will not load the desktop page but instead load the mobile page.

My actual result:

  1. When the desktop user visit path checkout/1, it will load the desktop page.
  2. When the mobile user visit path checkout/1, it will not load any page.

checkout-page-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { IsDesktopGuard } from '../../../domain/usecases/is-desktop/is-desktop.guard';

const routes: Routes = [
  {
    path: '',
    loadChildren: () => import("../checkout-scroll-page/checkout-scroll-page.module").then(m => m.CheckoutScrollPageModule),
    canLoad: [IsDesktopGuard]
  },
  {
    path: '',
    loadChildren: () => import("../checkout-navigate-page/checkout-navigate-page.module").then(m => m.CheckoutNavigatePageModule)
  }
];

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


Solution

  • You can conditionally do loadChildren based on the device?

    const isMobile = {
      Android: function () {
        return navigator.userAgent.match(/Android/i);
      },
      BlackBerry: function () {
        return navigator.userAgent.match(/BlackBerry/i);
      },
      iOS: function () {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
      },
      Opera: function () {
        return navigator.userAgent.match(/Opera Mini/i);
      },
      Windows: function () {
        return navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i);
      },
      any: function () {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
      }
    };
    
    const routes: Routes = [
      {
        path: 'desktop',
        loadChildren: () => {
          if (!isMobile.any()) {
            return import("../checkout-scroll-page/checkout-scroll-page.module").then(m => m.CheckoutScrollPageModule);
          } else {
            return import("../checkout-navigate-page/checkout-navigate-page.module").then(m => m.CheckoutNavigatePageModule);
          } 
         },
      },
    ];