1

I would like to be able to display different components based on the device the application is being viewed on. I am currently using the below to change the component and it works. The issue is that it is based on the screen width and not based on the device the user is viewing it on.

export const isDesktop = (): boolean => {
    return window.innerWidth > 768
}

export const routes: Routes = [
    {
        path: "",
        component: AppLayoutComponent,
        children: [
            { path: "route1", loadComponent: () => isDesktop() ? import("./pages/desktop/component1.component") : import("./pages/mobile/component1.component") },
            { path: "route2", loadComponent: () => isDesktop() ? import("./pages/desktop/component2.component") : import("./pages/mobile/component2.component") }
    ]
  }
];

I have found that other users use the ngx-device-detector package to determine the device type and I would like to be able to use this if possible but I cannot workout how I can use an instance of this service within the route array.

What I would like to be able to do is something like the below, but clearly this won't work.

import { DeviceDetectorService } from 'ngx-device-detector';

export const isDesktop = (): boolean => {
    const service = inject(DeviceDetectorService);
    return !service.isMobile();
}

Would you be able to advise if the way I am attempting this is totally wrong and give a suggested alternative approach, or would you know how I can get access to that service within the route array?

2 Answers 2

1

You can write a function, that checks the device using navigator object's userAgent property of the browser.

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());
  }
};

export const routes: Routes = [
    {
        path: "",
        component: AppLayoutComponent,
        children: [
            { path: "route1", loadComponent: () => !isMobile.any() ? import("./pages/desktop/component1.component") : import("./pages/mobile/component1.component") },
            { path: "route2", loadComponent: () => !isMobile.any() ? import("./pages/desktop/component2.component") : import("./pages/mobile/component2.component") }
    ]
  }
];

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for providing a solution, this may work but I personally don't like this solution as it is very verbose and is not really what I wanted. You did however point me in the direction of the CanMatch guard which gave me a solution to the problem.
1

I found an answer to my problem, I am not sure if it is the best solution but it is the best I have found so far.

I have used two CanMatch guards, one for Mobile and one for Desktop.

mobile.guard.ts

@Injectable({
    providedIn: 'root'
  })
export class MobileGuard implements CanMatch {
    private deviceDetectorService = inject(DeviceDetectorService);
    canMatch(): MaybeAsync<GuardResult> {
        return this.deviceDetectorService.isMobile();
    }
}

desktop.guard.ts

@Injectable({
    providedIn: 'root'
  })
export class DesktopGuard implements CanMatch {
    private deviceDetectorService = inject(DeviceDetectorService);
    canMatch(): MaybeAsync<GuardResult> {
        return !this.deviceDetectorService.isMobile();
    }
}

In my routes I have done the following:

export const routes: Routes = [
    {
        path: "",
        component: AppLayoutComponent,
        children: [
            { path: "route1", loadComponent: () => import("./pages/mobile/component1.component"), canMatch: mapToCanMatch([MobileGuard]) },
            { path: "route1", loadComponent: () => import("./pages/desktop/component1.component"), canMatch: mapToCanMatch([DesktopGuard]) },

    ]
  }
];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.