Making a screen that appears only upon first time opening the app. The second time that the user opens the app, that screen wont appear again

Hello :slight_smile: I am struggling with creating a feature in my app. I wish to make an “Welcome” screen in my app that appears only the first time that the user has opened an app and then never again.

So what I’m struggling with is how to approach making this feature… my plan is to create a page component with a button to navigate to the login screen. But what I don’t know is how save that state that his screen has already been seen by the user and the app should not load it upon second time opening the app…

I am assuming that
1.) I need to make a service that will get and set data in the storage memory (Do I use the capacitor PREFERENCES for this or ionic storage?)
2.) I need to check if there is welcomeScreenShown variable set in the storage, and read it’s value. (How and where?)
3.) if it’s false, then display the welcome screen and then set the welcomeScreenShown to true, so next time the screen won’t be displayed and it will reroute the user to the homepage

Is this correct? Has anyone done such a thing and could someone provide some code for reference?

Thank you all so much :slight_smile:

Sounds like a correct way of doing so :blush: I would recommend using the Ionic Storage in combination with the SQLite plugin

Well I tried using Ionic Storage but am getting a warning in CLI in console…

WARNING
/…/…/…/…/Angular/my-app/node_modules/@ionic/storage/dist/esm/index.js depends on ‘localforage’. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see:

only a warning, don’t worry. Do get rid of it add it into allowedCommonJsDependencies as described here: javascript - Upgrading to Angular 10 - Fix CommonJS or AMD dependencies can cause optimization bailouts - Stack Overflow

You may write a page guard which check for stored value

canActivate(route: ActivatedRouteSnapshot):  Promise<boolean>  
  { 
    return new Promise(resolve => {
          this.storageService.getValue('first_time').then((val) => {
            if (val !== null) {
              this.router.navigateByUrl('/login')
              resolve(false);
            } 
            else {              
                this.storageService.setValue('first_time', 'done');
                resolve(true);
            }
        });
    })
  }

Apply guard for routing module

 {
    path: 'startup',
    loadChildren: () => import('./pages/common/startup/startup.module').then( m => m.StartupPageModule),
    canActivate:[FirstLoadCheckGuard]
  },

Thank you for this, could you also please provide code to how exactly would the storage service set value and get value function?

You may use local storage as per requirement

import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage-angular';

@Injectable({
  providedIn: 'root'
})
export class AppstorageService {

  constructor(private storage: Storage) {
    this.initStorage();
   }

  async initStorage() {
    await this.storage.create();
  }

  async setValue(key,value) {
    await this.storage.set(key, value);  
    return true;
  }

  async getValue(key) {
    const value = await this.storage.get(key);   
    return value;
  }

  async removeValue(key)
  {
      await this.storage.remove(key);
      return
  }
}

Thank you werry much :slight_smile:

So now I have an issue that my app keeps skipping the startup page and goes straight to login and when I try to log in it stays on this page… the console.log show that the state is set to done…

so here is how my code looks like now:
app-routing.module.ts:

const routes: Routes = [
  {
    path: 'login',
    loadChildren: () => import('./login/login.module').then( m => m.LoginPageModule),
    canLoad: [AutoLoginGuard]
  },
  {
    path: '',
    redirectTo: 'startup',
    pathMatch: 'full'
  },
  {
    path: 'startup',
    loadChildren: () => import('./pages/startup/startup.module').then( m => m.StartupPageModule),
    canActivate:[FirstLoadGuard]
  },
  {
    path: 'home',
    loadChildren: () => import('./home/home.module').then( m => m.HomePageModule),
    canLoad: [AuthGuard],
  },
];

this is the code of storage.service.ts:

export class StorageService {
  constructor(private storage: Storage) {
    this.initStorage();
    console.log('Init storage');
  }

  async initStorage() {
    await this.storage.create();
    console.log('Storage ustvarjen');
  }

  async setValue(key,value) {
    await this.storage.set(key, value);
    return true;
  }

  async getValue(key) {
    return await this.storage.get(key);
  }
}

this is the first-load.guard.ts:

export class FirstLoadGuard implements CanActivate {
  constructor(
    private storageService: StorageService,
    private router: Router
  ) {}
  canActivate(route: ActivatedRouteSnapshot):  Promise<boolean>
  {
    return new Promise(resolve => {
      this.storageService.getValue('first_time').then((value) => {
        if (value !== null) {
          this.router.navigateByUrl('/login');
          console.log('guard if value: ', value);
          resolve(false);
        }
        else {
          this.storageService.setValue('first_time', 'done');
          resolve(true);
        }
      });
    });
  }
}

so what have I done wrong? I want the user to see this startup page then click a button to go to login and continiue using the app… and next time he opens the app the app doesent show the startup screen

FirstLoadCheckGuard : as shared before
AppStorageService: as shared before

Login guard : returning true just to test

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { take, map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class LoginGuard implements CanActivate {
  constructor(
    private router: Router, 
    //private userAccountService:UserAccountService
    ) { }
 
  canActivate(
    route: ActivatedRouteSnapshot):  boolean 
    {
      return true;
    }  
}

app.routes.ts

export const routes: Routes = [ 
  {
    path: '',
    redirectTo: 'startup',
    pathMatch: 'full'
  },
  {
    path: 'login',
    loadComponent: () => import('./login/login.page').then( m => m.LoginPage),
    canActivate: [LoginGuard]
  },
  {
    path: 'startup',
    loadComponent: () => import('./startup/startup.page').then( m => m.StartupPage),
    canActivate:[FirstLoadCheckGuard]
  },
  {
    path: 'home',
    loadComponent: () => import('./home/home.page').then((m) => m.HomePage),

  },
];

Run it on web browser first so that you can clear the storage manually and test again and again.

This code is tested on browser as well as on emulator, its working fine

Thank you so much for this <3

1 Like