Put your app on your phone!
- Install the NativeScript command line interface
sudo npm install --global nativescript - We need to perform two extra steps because NativeScript is not yet fully compatible with Angular 10 (at the time of writing)
- Remove the first line (as below) from the files tsconfig.app.json and tsconfig.base.json
/* To learn more about this file see: https://angular.io/config/tsconfig. */ - Install the Angular 9 version of schematics
npm install --save-dev @schematics/angular@^9
- Remove the first line (as below) from the files tsconfig.app.json and tsconfig.base.json
- Add NativeScript to your app
ng add @nativescript/schematics - Run your app to check that it still works as before in the web browser
- Now we need a couple more tweaks and we're good to go
- Install version 5 of the copy-webpack-plugin
npm install --save copy-webpack-plugin@^5 - Add the following two lines to the end of the "compilerOptions" section in tsconfig.tns.json
"baseUrl": "./", "experimentalDecorators": true- You will also need to add a comma at the end of the preceding line which contains a single curly bracket
- Install version 5 of the copy-webpack-plugin
- Build the NativeScript app
tns preview- This will display a QR code on your screen
- To preview your app on your phone, you need to install two companion apps on your Android/iOS device(s):
- Scan the QR code with the NativeScript Playground app, which will connect your project with the NativeScript Preview app
- If everything works, you will see the following on your phone: "auto-generated works!"
- As always commit and synchronize your changes
We want our heroes to work in the web browser and the mobile app.
- Make sure you read and follow these instructions carefully!
- Migrate the app navigation
- Add a shared file with the routes configuration in src/app: app.routes.ts
import { Routes } from '@angular/router'; - Cut and paste this code block from app-routing-module.ts to app.routes.ts
const routes: Routes = [ ... ];- We also need to export the routes, so change the first line to
export const routes: Routes = [
- We also need to export the routes, so change the first line to
- Also cut and paste these import statements from app-routing-module.ts to app.routes.ts
import { DashboardComponent } from './dashboard/dashboard.component'; import { HeroesComponent } from './heroes/heroes.component'; import { HeroDetailComponent } from './hero-detail/hero-detail.component'; - Add the following import to app-routing-module.ts
import { routes } from './app.routes';- Change this line from
import { RouterModule, Routes } from '@angular/router'; - To
import { RouterModule } from '@angular/router';
- Change this line from
- Remove this code block from app-routing-module.tns.ts
export const routes: Routes = [ ... ]; - Add the following import to app-routing-module.tns.ts
import { routes } from './app.routes';- And remove these two
import { Routes } from '@angular/router'; import { AutoGeneratedComponent } from '@src/app/auto-generated/auto-generated.component';
- And remove these two
- Add a shared file with the routes configuration in src/app: app.routes.ts
- To get rid of the warning regarding 'Experimental support for decorators'
- Go to Preferences -> Settings in Visual Studio Code
- Enter 'decorator' into the search box
- Enable the option for experimentalDecorators
- Commit and synchronize your changes
- We won't be reminding you about this anymore
- By now you surely noticed how useful it is to compare against the last working version in the Source Control tab of Visual Studio
Today we'll prepare our components for the mobile app.
- Remove the auto-generated component
- Delete the complete folder src/app/auto-generated in Visual Studio
- In app.module.ts and app.module.tns.ts remove the following two lines
import { AutoGeneratedComponent } from '@src/app/auto-generated/auto-generated.component'; AutoGeneratedComponent,
- Migrate the components
ng g migrate-component --name=dashboard ng g migrate-component --name=hero-detail ng g migrate-component --name=heroes - If you open the file app.module.tns.ts, you will notice that all imports starting with '@src/app/..' are marked as invalid
- This is a Visual Studio Code issue and won't affect your app
- From the Extensions tab in Visual Studio install the NativeScript extension
- Let's see what our mobile app looks like now
tns preview- Scan the QR code using the NativeScript Playground app
Our web app is quite nice, but we want our mobile app to feel like an app, not a web site.
- In main.tns.ts replace
platformNativeScriptDynamic().bootstrapModule(AppModule);- With
platformNativeScriptDynamic({createFrameOnBootstrap: true}).bootstrapModule(AppModule);
- With
- Replace the first line of app.component.tns.html with these
<ActionBar title="{{title}}"> <ActionItem text="Dashboard" (tap)="dashboard()"></ActionItem> <ActionItem text="Heroes" (tap)="heroes()"></ActionItem> </ActionBar> - In app.component.tns.ts
- After this line
import { Component } from '@angular/core';- Add
import { Router } from '@angular/router';
- Add
- After this line
export class AppComponent { }- Add
constructor(private router: Router) { } dashboard() { this.router.navigateByUrl("/dashboard"); } heroes() { this.router.navigateByUrl("/heroes"); } - Remove the closing curly bracket } from
export class AppComponent { } - And add it on a new line after the code block you just inserted
- Use the tab key to indent the new code block by two spaces
- Add
- After this line
- Start the mobile app
tns preview - Replace the content of dashboard.component.tns.html with
<StackLayout> <Label text="Top Heroes" class="h3" textAlignment="center"></Label>/> <StackLayout orientation="horizontal"> <Button *ngFor="let hero of heroes" textAlignment="center" class="h4" text="{{hero.name}}" nsRouterLink="/detail/{{hero.id}}"></Button> </StackLayout> </StackLayout> - Restart the mobile app if necessary
- Replace hero-detail.component.tns.html with
<StackLayout *ngIf="hero"> <Label text="{{hero.name | uppercase}} Details" class="h2"></Label> <Label text="id: {{hero.id}}"></Label> <Label text="name:"></Label> <TextField [text]="hero.name"></TextField> </StackLayout>
We will use a native list view component to display your heroes on your phone.
- Install the NativeScript ListView from the terminal
tns plugin add nativescript-ui-listview@rc- At the time of writing we need to use the release candidate (rc) version for compatibility with Angular 10
- Edit app.module.tns.ts
- After this line
import { NativeScriptModule } from '@nativescript/angular';- Add
import { NativeScriptUIListViewModule } from "nativescript-ui-listview/angular";
- Add
- After
imports: [ NativeScriptModule,- Add
NativeScriptUIListViewModule,
- Add
- After this line
- Replace heroes.component.tns.html with
<StackLayout> <Label text="My Heroes" class="h2"></Label>/> <ListView [items]="heroes" (itemTap)="onSelectHero($event)"> <ng-template let-hero="item"> <StackLayout orientation="horizontal"> <Label textAlignment="right" [text]="hero.id"></Label> <Label textAlignment="left" [text]="hero.name"></Label> </StackLayout> </ng-template> </ListView> </StackLayout> - In heroes.component.ts
- Add the following imports
import { Router } from '@angular/router'; import { ItemEventData } from '@nativescript/core/ui/list-view/list-view'; - Change the constructor to
constructor(private heroService: HeroService, private router: Router) { } - After the method getHeroes() add a new method
onSelectHero(event: ItemEventData) { const hero = this.heroes[event.index]; this.router.navigateByUrl("/detail/" + hero.id); }
- Add the following imports
- Test your mobile app and verify that everything works like in the web version
Your app should offer a consistent user experience which is optimized for web and mobile versions.
- Use consistent font sizes
- We use h1 for the app title and h2 for page titles
- Adjust dashboard.component.html to use the h2 style to display the title
- Adjust dashboard.component.tns.html to use the h2 style to display the title
- Alignment of the page title
- For the web app we will align titles left, the mobile app looks better with centered titles
- Add the following attribute to the first label in hero-detail.component.tns.html and heroes.component.tns.html
textAlignment="center"- Add it to the Label between class="h2" and >
- Run both the web and mobile apps
- Notice how the titles on all pages are now displayed the same
- Open the HERO Details page in your web browser
- Notice these layout issues
- id: and name: are too far to the left
- The hero name text field is displayed right below the label name:
- The buttons have very small text
- Notice these layout issues
- Adjust the padding for the hero detail page
- In hero-detail.component.scss after
/* HeroDetailComponent's private CSS styles */- Add
div { padding-left: .2em; }
- Add
- Also in hero-detail.component.scss add the following for: input {
margin-top: .2em;- On a new line before the closing curly bracket }
- In hero-detail.component.tns.html
- Add the following attribute for the id: and name: Labels
class="m-x-15"
- Add the following attribute for the id: and name: Labels
- In hero-detail.component.scss after
- Increase size of button text for the web app
- In styles.scss before the following line
/* everywhere else */ - Add
button { font-size: 100%; }
- In styles.scss before the following line
- Only show the back button for the hero details page in the mobile app
- In app.component.tns.ts
- Replace
import { Router } from '@angular/router';- With
import { RouterExtensions } from '@nativescript/angular/router';
- With
- Replace everything within
export class AppComponent { ... }- With
constructor(private routerExtensions: RouterExtensions) { } dashboard() { this.routerExtensions.navigateByUrl("/dashboard", { clearHistory: true }); } heroes() { this.routerExtensions.navigateByUrl("/heroes", { clearHistory: true }); }
- With
- If you get stuck doing the changes to a file, revert your changes to this file in the Source Control tab and start fresh
- Run the mobile app and observe the changes
We wrote a lot of code in the last weeks. Now's the time to learn more about its structure so you can write your own code.
- Install the Mimo app on your phone or tablet
- Use these settings
- Choose your personal motivation
- No coding experience
- Web Development path
- Regular, 10 minutes per day
- Enable daily notification at a convenient time
- Create a profile
- Skip the free trial, we only need the basic features
- Work through the daily Mimo lesson
- Repeat daily until you complete the Web Development path