Change page based on user logged in at the base url

I want my app to use the root url (ex. www.myawesomewebsite.com) to show a login page or if the user is logged in show their profile. I don’t want to route to their profile page, I am trying to dynamically show their profile if they are logged in on the root of the site.

I have this working but the profile page is not full viewport. I am switching between the 2 with a check in my auth service. I know it is not getting the ion-page class but i don’t know why. I am sure this is a simple fix but I am a noob to ionic and angular. code below.

app-routing.module.ts:

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

const routes: Routes = [
  {
    path: '',
    redirectTo: 'home',
    pathMatch: 'full'
  },
  {
    path: '',
    loadChildren: () => import('./home/home.module').then( m => m.HomePageModule)
  },
  {
    path: 'forgot-password',
    loadChildren: () => import('./forgot-password/forgot-password.module').then( m => m.ForgotPasswordPageModule)
  },
  {
    path: 'sign-up',
    loadChildren: () => import('./sign-up/sign-up.module').then( m => m.SignUpPageModule)
  },
  {
    path: 'profile',
    loadChildren: () => import('./profile/profile.module').then( m => m.ProfilePageModule)
  },
];

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

home.page.html:

<app-profile *ngIf="isAuthenticated()"></app-profile>

<ion-content *ngIf="!isAuthenticated()">
  <ion-grid class="ion-no-padding" >
    <ion-row>
      <ion-col size="12" size-md="6"  class="left">
          <div class="box">
          <ion-img src="/assets/img/logo-tag.png"></ion-img>
        </div>
      </ion-col>
      <ion-col size="12" size-md="6"  class="right">
        <ion-row>
          <ion-col class="log-in">
            <div class="top">
              <app-login></app-login>
            </div>
          </ion-col>
        </ion-row>
        <ion-row>
          <ion-col class="sign-up">
            <div class="bot">
                <p>connect to your interests and define the world, start now</p>
                <p class="small">join nyched today!</p>
                <ion-button role="button" color="light" expand="block" shape="round" fill="outline" (click)="openSignupModal()">sign up</ion-button>
              </div>
            </ion-col>
          </ion-row>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

home.page.ts:

import { Component} from '@angular/core';
import { ModalController } from '@ionic/angular';
import { AuthService } from '../components/auth.service';
import { SignUpPage } from '../sign-up/sign-up.page';



@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  constructor(
    private modalCtrl: ModalController,
    private authService: AuthService
  ) {}

  openSignupModal() {
    this.modalCtrl
      .create({
        component: SignUpPage
      }).then(modalEl => {
        modalEl.present();
      });
  }
  isAuthenticated() {
    return this.authService.userIsAuthenticated;
  }

}

profile.page.html:

<ion-header>
  <ion-toolbar color="primary">
    <ion-grid>
      <ion-row>
        <ion-col size="2" offset="5" class="ion-text-center">
          <img src="/assets/img/logo-icon.png" class="img-mobile ion-hide-md-up"/>
          <img src="/assets/img/logo.png" class="img-desktop ion-hide-md-down"/>
        </ion-col>
      </ion-row>
    </ion-grid>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-grid>
    <ion-row>
      <ion-col>
        <p>Profile is working</p>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

profile.page.ts:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.page.html',
  styleUrls: ['./profile.page.scss'],
})
export class ProfilePage implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

auth.service.ts:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private _userIsAuthenticated = false;
  private _userId = '1';

/*eslint no-underscore-dangle: ["error", { "allowAfterThis": true }]*/
  get userIsAuthenticated() {
    return this._userIsAuthenticated;
  }

  get userId() {
    return this._userId;
  }

  constructor() { }

  login(){
    this._userIsAuthenticated = true;
  }

  logout(){
    this._userIsAuthenticated = false;
  }
}

Despite the fact that they look very similar in Angular (@Component decoration), I think it’s a good idea to pretend that components and pages are completely different beasts, because (as you’re encountering) they aren’t precisely interchangeable.

Here’s how I think of it: pages can be routed to. Components can’t. Components can be embedded into components or into pages, pages can’t be.

So, if we accept as axiomatic that the “profile” you want to display needs to sometimes be embedded alongside some other stuff in a page, it itself can’t be a page, but must rather be a component.

If you also want to display the profile as a standalone page sometimes, then make a separate ProfilePage with a very simple template that just contains the ProfileComponent.

That makes sense. So if I am only ever going to show the profile at the root then it should be a component instead of a page. If I want to use it somewhere as a page I should essentially make a page version of the profile?

Thanks for the help!

I converted the profile page to a component. Part of the issue was that there were 2 ion-content. So I refactored the code to have the header in the home page and used the authentication bool on the header and the children of the ion-content. Then removed the header and ion-content from the profile component. Working code below.

home.page.html:

<ion-header *ngIf="isAuthenticated()">
  <ion-toolbar color="primary">
    <ion-grid>
      <ion-row>
        <ion-col size="2" offset="5" class="ion-text-center">
          <img src="/assets/img/logo-icon.png" class="img-mobile ion-hide-md-up"/>
          <img src="/assets/img/logo.png" class="img-desktop ion-hide-md-down"/>
        </ion-col>
      </ion-row>
    </ion-grid>
  </ion-toolbar>
</ion-header>
<ion-content>
  <app-profile *ngIf="isAuthenticated()"></app-profile>
  <ion-grid *ngIf="!isAuthenticated()" class="ion-no-padding">
    <ion-row>
      <ion-col size="12" size-md="6"  class="left">
          <div class="box">
          <ion-img src="/assets/img/logo-tag.png"></ion-img>
        </div>
      </ion-col>
      <ion-col size="12" size-md="6"  class="right">
        <ion-row>
          <ion-col class="log-in">
            <div class="top">
              <app-login></app-login>
            </div>
          </ion-col>
        </ion-row>
        <ion-row>
          <ion-col class="sign-up">
            <div class="bot">
                <p>isAuthenticated = {{ isAuthenticated() }}</p>
                <p>connect to your interests and define the world, start now</p>
                <p class="small">join nyched today!</p>
                <ion-button role="button" color="light" expand="block" shape="round" fill="outline" (click)="openSignupModal()">sign up</ion-button>
              </div>
            </ion-col>
          </ion-row>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

profile.component.html:

  <ion-grid>
    <ion-row>
      <ion-col>
       <p>profile working</p>
      </ion-col>
    </ion-row>
  </ion-grid>

Thanks for reporting back: it will help others in a similar situation.

It would not surprise me if your next issue is how to smoothly propagate login/logout and profile information throughout the app; please let me preemptively suggest this idiom.

1 Like

Sure thing. I’ve been a developing for the web since I was 10. Made good use of the old <marquee></marquee> in my day, haha. I’ve always made it a practice, when i take the time to reach out for help, to post my solution if I find it on my own.

And thank you for the advice. If it becomes an issue I am not opposed to changing the apps url structure. I just think it looks nicer this way for what I am doing. I hope to contribute more in the future!