'How to implement two html files for the same component in angular 9? One for mobile sized and one for desktop?

I would like to implement an application with multiple components and modules using Angular Material for desktop and Ionic for mobile. So far, the solution I found is to create two different lazy modules and config the routes based on window-sized.

For example, in order to create a page, I should create a component in the mobile module and a similar one in the desktop module. As you can guess, the logic of my component is copied into two seperate ts files while it should be in one ts file. As the application grows, the maintenance of the project will be harder and harder.

Question

How can I have only one ts file for each component and inject the suitable HTML (or probably CSS) based on window size? It is very important to make both views lazy loaded, so when a user reaches the site via mobile will not download the desktop view.

Desirable result as something like this:

@Component({
  selector: 'app-example',
  templateUrl: isMobile == true ? './desktop.html' : './mobile.html',
})


Solution 1:[1]

Based on your use case, instead of having more than 1 html for a same ts file, a better, easily maintainable solution would be to use the angular features such as ngIf or to use media queries.

  1. NgIf - If the page is more or less common, simple styling changes can work perfectly well for both web and for mobile based UI. Since angular supports bootstrap, it can be very simple. What you can have is 2 views, 1 of which to display can be chosen on runtime. In the constructor or ngOnInit, you can assign the isMobile variable and accordingly take a decision.

  2. Media queries - A proper styling, coupled with media queries can help you convert the same web page into something that is fit for mobiles, tablets, etc. The maintainability is highly increased since now, you just have to maintain the HTML in a single file only.

I hope this helps. Please let me know if you have any follow up queries.

Solution 2:[2]

Upon checking the link you have given and inspecting it i think the web view is an angular project whereas in mobile it seems its an ionic-angular project ....

So i came to the conclusion that it may be two separate applications one being angular webapp and another an ionic-angular hybrid app in separate folders respectively rather than one.

I imagine the configuration to use a specific folder based on certain params, one being user agents might be setup at server level via an .htaccess file or some other file based on the deployment server.

If the site is mobile viewed using inspector of browser you will get a view that is setup using media queries probably and shows only router-outlet tag(angular app)

whereas on reload it sends a new request satisfying the mobile view folder conditions thereby leading to an ionic app confirmed by noticing the ion-router-outlet tag

enter image description here

enter image description here

enter image description here

Refer this for some idea regarding the htaccess method -> Mobile Redirect using htaccess

Alternatively i would prefer what Ankit Joshi has said

Solution 3:[3]

You can use the component inheritance feature

Create a Basic component that includes all logic, lifecycle hooks, and others that you need in the integration typescript file.

Create 2 components for mobile and desktop and implement your HTML specifically then typescript files inherited from the basic component typescript file.

Basic component:

@Component({
  template: ''
})

export class BaseComponent implements OnInit {

  constructor(public router: Router , ...) { }

  ngOnInit(): void {
    // do something
  }

  myFunction(param: string) {
    console.log(param);
  }
  .
  .
  .

}

Desktop component:

@Component({
  selector: 'app-desktop',
  templateUrl: './desktop.component.html', //Special template for Desktop
  styleUrls: ['./desktop.component.css']
})
export class DesktopComponent extends BaseComponent {

  constructor(public router: Router , ...) {
    super(router , ...);
  }

}

Mobile component:

@Component({
  selector: 'app-mobile',
  templateUrl: './mobile.component.html', //Special template for mobile
  styleUrls: ['./mobile.component.css']
})
export class MobileComponent extends BaseComponent {

  constructor(public router: Router , ...) {
    super(router , ...);
  }

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ankit Joshi
Solution 2 stannars jose
Solution 3