Slide 1

Slide 1 text

Modern Web Apps with Spring Boot & Angular Kai Tödter 11/11/2022 1 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License.

Slide 2

Slide 2 text

Who am I? ▪ Principal Key Expert at Siemens Smart Infrastructure ▪ Web Technology Fan ▪ Open Source Lover ▪ E-mail: [email protected] ▪ Twitter: twitter.com/kaitoedter ▪ Mastodon: https://mastodon.social/@kaitoedter 11/11/2022 2 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License.

Slide 3

Slide 3 text

Show Hands! 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 3

Slide 4

Slide 4 text

Spring Boot? Hypermedia? TypeScript? Angular? Bootstrap? 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 4

Slide 5

Slide 5 text

After this tutorial I’ll have an idea how to put it all together! 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 5

Slide 6

Slide 6 text

Outline ▪ Spring Boot ▪ REST & Hypermedia ▪ Spring Data REST ▪ TypeScript ▪ Angular ▪ Bootstrap ▪ Putting it all together 11/11/2022 6 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License.

Slide 7

Slide 7 text

What we will create… 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 7

Slide 8

Slide 8 text

Requirements: Labs on local Machine ▪ Your favorite text editor or IDE ▪ Eclipse, IntelliJ IDEA, Sublime, … ▪ Java >= 11 (JDK) installed ▪ Node.js installed 11/11/2022 8 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License.

Slide 9

Slide 9 text

Lab 0: Check Build Environment ▪ Install the tutorial sources ▪ Clone https://github.com/toedter/webapp-tutorial ▪ Open terminal and cd into webapp-tutorial ▪ gradlew build ▪ Linux & Mac: ./gradlew build ▪ If the build is successful, you are ready to go! 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 9

Slide 10

Slide 10 text

Optional: Try out Gidpod ▪ Open https://gitpod.io/#https://github.com/toedter/webapp-tutorial in Web browser ▪ Log-in using GitHub 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 10

Slide 11

Slide 11 text

Gitpod Ready to Go! 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 11

Slide 12

Slide 12 text

11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 12

Slide 13

Slide 13 text

Why Spring Boot? ▪ Fast way to build web applications ▪ Inspects your classpath and beans you have configured ▪ You can focus more on business features and less on infrastructure ▪ Easily deployable as microservice 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 13

Slide 14

Slide 14 text

What does Spring Boot NOT? ▪ Generate code ▪ Change your configuration 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 14

Slide 15

Slide 15 text

HelloController @RestController public class HelloController { @RequestMapping("/") public String index() { return "Greetings from Spring Boot!"; } } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 15

Slide 16

Slide 16 text

Application @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication .run(Application.class, args); } } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 16

Slide 17

Slide 17 text

Controller Test with MockMVC @WebMvcTest(HelloController.class) public class HelloControllerTest { @Autowired private MockMvc mockMVC; @Test public void shouldGetGreeting() throws Exception { mockMVC.perform(MockMvcRequestBuilders.get("/") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo( HelloController.LAB1_GREETINGS_FROM_SPRING_BOOT))); } } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 17

Slide 18

Slide 18 text

Integration Test with Random Port @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class HelloControllerIntegrationTest { @Autowired private TestRestTemplate restTemplate; @Test public void shouldGetGreeting() throws Exception { ResponseEntity response = restTemplate.getForEntity("/", String.class); assertThat(response.getBody(), equalTo(HelloController.LAB1_GREETINGS_FROM_SPRING_BOOT)); } } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 18

Slide 19

Slide 19 text

Lab 1: Task 1 ▪ Open lab1/complete in your IDE ▪ Run Application.java ▪ Open browser with localhost:8080 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 19

Slide 20

Slide 20 text

Lab 1: Task 2 ▪ Open lab1/initial in your IDE ▪ Create a Spring Boot based web app ▪ Run it and open your browser with localhost:8080 ▪ Optional: Write some tests! ▪ Get some ideas from …/complete 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 20

Slide 21

Slide 21 text

11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 21 REST + Hypermedia Basics

Slide 22

Slide 22 text

Outline ▪ REST Basics ▪ HATEOAS ▪ Hypermedia with HAL ▪ Spring Data REST 11/11/2022 22 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License.

Slide 23

Slide 23 text

What is REST? ▪ Stands for Representational State Transfer ▪ Is a Software Architecture Style ▪ was introduced and defined in 2000 by Roy T. Fielding in his doctoral dissertation ▪ REST != CRUD via HTTP 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 23

Slide 24

Slide 24 text

REST Architectural Constraints ▪ Client-Server ▪ Stateless ▪ Cacheable ▪ Layered system ▪ Code on demand (optional) ▪ Uniform interface (see next slide) 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 24

Slide 25

Slide 25 text

Uniform Interface ▪ Identification of resources ▪ Manipulation of resources through their representations ▪ Create => HTTP POST ▪ Read => HTTP GET ▪ Update => HTTP PUT, HTTP PATCH ▪ Delete => HTTP DELETE ▪ Self-descriptive messages ▪ Hypermedia as the engine of application state (HATEOAS) 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 25

Slide 26

Slide 26 text

Richardson Maturity Model Level 3: Hypermedia Controls Level 2: HTTP Verbs Level 1: Resources Level 0: The Swamp of POX 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 26 Source: https://martinfowler.com/articles/richardsonMaturityModel.html

Slide 27

Slide 27 text

Hypermedia APIs for Services are like Web Pages with Links for Humans 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 27

Slide 28

Slide 28 text

11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 28 HAL Image Source: http://wallpoper.com/images/00/26/43/92/hal-9000_00264392.jpg

Slide 29

Slide 29 text

HAL ▪ Is for Hypertext Application Language ▪ Was created by Mike Kelly ▪ Representations for both JSON and XML ▪ Very popular 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 29

Slide 30

Slide 30 text

HAL Structure 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 30 Plain old JSON Properties Links Plain old JSON Properties Links Plain old JSON Properties Links … Embedded Resources Embedded Resources Embedded Resources

Slide 31

Slide 31 text

HAL Example { "id":1, "text":"hello all!", "_links": { "self": { "href":"http://localhost:8080/chatty/api/messages/1" } }, "_embedded": { "author": { "id":"toedter_k" } } } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 31

Slide 32

Slide 32 text

Spring ▪ Spring Boot ▪ Spring Data REST ▪ Spring HATEOAS 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 32

Slide 33

Slide 33 text

Spring Data Rest: Domain @Data @Entity @NoArgsConstructor public class User { @Id private String id; private String fullName; private String email; } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 33

Slide 34

Slide 34 text

Spring Data REST: Repository @RepositoryRestResource( collectionResourceRel = "users", path = "users") interface UserRepository extends PagingAndSortingRepository { } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 34

Slide 35

Slide 35 text

Spring Data REST: Repository (2) @RepositoryRestResource( exported = false ) interface UserRepository extends PagingAndSortingRepository { } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 35

Slide 36

Slide 36 text

Spring Data REST: JSON Result { _links: { self: { href: "http://localhost:8080/chatty/api/users{?page,size,sort}", templated: true } }, _embedded: { users: [ { fullName: "Jane Doe", email: "[email protected]", _links: { self: { href: "http://localhost:8080/chatty/api/users/doe_ja" }, … 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 36

Slide 37

Slide 37 text

Robust Clients ▪ Start from main API ▪ Find link relations through defined contracts ▪ Follow Links ▪ For navigation ▪ For possible “actions” => Clients are robust regarding changes in link URIs 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 37

Slide 38

Slide 38 text

Controversial Discussion ▪ Are we there yet? ▪ RESTistential Crises ▪ http://www.infoq.com/news/2014/03/rest-at- odds-with-web-apis ▪ DHH, Getting hyper about hypermedia apis ▪ https://signalvnoise.com/posts/3373-getting- hyper-about-hypermedia-apis 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 38

Slide 39

Slide 39 text

Live Demo + Tests 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 39

Slide 40

Slide 40 text

Lab 2: Task 1 ▪ Open lab2/complete in your IDE ▪ Run Application.java ▪ Open browser with localhost:8080 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 40

Slide 41

Slide 41 text

Lab 2: Task 2 ▪ Open lab2/initial in your IDE ▪ Add a user repository ▪ Fill the repository with test data ▪ Run the application and open your browser with localhost:8080 ▪ Optional: Write some tests! ▪ Get some ideas from ../complete 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 41

Slide 42

Slide 42 text

11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 42 TypeScript & Angular

Slide 43

Slide 43 text

Outline ▪ TypeScript Introduction ▪ Angular Introduction ▪ TypeScript + Angular ▪ Demos & Live Coding 11/11/2022 43 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License.

Slide 44

Slide 44 text

JavaScript? Many Java/OO developers don’t like JavaScript regarding writing larger applications. Some reasons are: ▪ No static typing ▪ No reliable code completion (only best guess) ▪ Hard to refactor ▪ Not object-oriented, especially ▪ No structuring mechanisms like Interfaces, Classes*, Modules* * Before ECMAScript 2015 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 44

Slide 45

Slide 45 text

Who fixes that? ▪ Dart ▪ Great language by Google: dartlang.org ▪ Team has to learn new language ▪ Either runs on Dart VM or compiles to JavaScript ▪ CoffeeScript ▪ Ruby-like, concise syntax ▪ Compiles to JavaScript ▪ coffeescript.org ▪ BabelJS ▪ JavaScript compiler ▪ babeljs.io ▪ Traceur ▪ JavaScript compiler ▪ github.com/google/traceur-compiler 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 45

Slide 46

Slide 46 text

TypeScript: Summary ▪ Typed Superset of JavaScript ▪ Almost all valid JavaScript is valid TypeScript* ▪ Compiles to JavaScript ▪ Provides optional static type checking at compile time ▪ For most existing JavaScript libraries there are type definitions available ▪ Provides Interfaces, Classes, Modules, Enums, Generics, Decorators and more ▪ Open Source: Apache 2.0 License ▪ Created by Microsoft 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 46

Slide 47

Slide 47 text

How to get started? ▪ www.typescriptlang.org ▪ Install Node.js (nodejs.org) ▪ Invoke “npm install –g typescript” ▪ Compile a TypeScript file: “tsc myTypeScript.ts” ▪ Results in “myTypeScript.js” 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 47

Slide 48

Slide 48 text

www.typescriptlang.org 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 48

Slide 49

Slide 49 text

Play! 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 49

Slide 50

Slide 50 text

Definitely Typed 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 50

Slide 51

Slide 51 text

Interfaces export interface User { getId(): string; getEmail(): string; getFullName(): string; } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 51

Slide 52

Slide 52 text

Classes export class SimpleUser implements User { constructor(private id: string, private email: string, private fullName: string) { } getId(): string { return this.id; } … 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 52

Slide 53

Slide 53 text

Live Demo 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 53

Slide 54

Slide 54 text

11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 54 JavaScript Dev Tools

Slide 55

Slide 55 text

JavaScript Dev Tools ▪ In JavaScript land, mostly JavaScript based tools are used for build, dependency management, test, etc. ▪ npm (or yarn) for ▪ dependency management (including @types) ▪ Running build/test/server scripts ▪ Jasmine for implementing tests ▪ Karma for running tests 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 55

Slide 56

Slide 56 text

npm ▪ Package manager for JavaScript ▪ Resolves dependencies ▪ Runs scripts ▪ Input file is package.json ▪ Alternative to npm: yarn 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 56

Slide 57

Slide 57 text

package.json Example (1) { "name": "tutorial-web-client", "title": "tutorial web client", "version": "1.0.0", "description": "tutorial web client", "scripts": { "build": "tsc", "test": "karma start" }, "author": { "name": "Kai Toedter", "url": "http://toedter.com" }, 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 57

Slide 58

Slide 58 text

package.json Example (2) "license": "MIT", "dependencies": { }, "devDependencies": { "jasmine-core": "~4.4.0", "jasmine-spec-reporter": "~7.0.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.1.1", "karma-coverage-istanbul-reporter": "~3.0.3", "karma-jasmine": "~5.1.0", "karma-coverage": "~2.2.0", "karma-jasmine-html-reporter": "^2.0.0", "typescript": "~4.8.2" } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 58

Slide 59

Slide 59 text

Jasmine Example describe('User', () => { it('should create user and get attributes', () => { var user:User = new SimpleUser("user1", "[email protected]", "User 1"); expect(user).toBeDefined(); expect(user.getId()).toBe('user1'); expect(user.getEmail()).toBe(' [email protected] '); expect(user.getFullName()).toBe('User 1'); }); }); 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 59

Slide 60

Slide 60 text

Since TypeScript 2.0: @types ▪ All typings are available as npm modules ▪ Install a typing with ▪ npm install @types/ ▪ E.g., npm install @types/jasmine 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 60

Slide 61

Slide 61 text

@types in tsconfig.json { "compilerOptions": { "module": "es2020 ", "target": "es2020 ", "outDir": "build/dist", "rootDir": ".", "sourceMap": true, "experimentalDecorators": true, "moduleResolution": "node", "typeRoots": [ "node_modules/@types" ] } } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 61

Slide 62

Slide 62 text

Karma ▪ Test runner for JavaScript ▪ Created by Google ▪ Supports different browsers ▪ Easy configuration 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 62

Slide 63

Slide 63 text

Karma Config Example module.exports = function(config) { config.set({ basePath: '.', frameworks: [ 'jasmine‘ ], files: [ 'dist/**/*.js' ], reporters: ['progress'], port: 9876, colors: true, autoWatch: false, browsers: ['Chrome'], singleRun: true, concurrency: Infinity }) } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 63

Slide 64

Slide 64 text

Lab 3: Task 1 ▪ Open terminal in lab3/complete ▪ export CHROME_BIN=/usr/bin/chromium-browser ▪ Invoke npm run build ▪ Check that all TypeScript files were transpiled to JavaScript in the dist directory ▪ Invoke npm test ▪ Check that the Karma run was successful ▪ And all Jasmine tests are green 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 64

Slide 65

Slide 65 text

Lab 3: Task 2 ▪ Complete initial implementation of ▪ User.ts, SimpleUser.ts, TestData.ts ▪ UserSpec.ts ▪ Open terminal in lab3/initial ▪ Invoke npm run build ▪ Check everything builds ▪ Invoke npm test ▪ Check that all tests are green 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 65

Slide 66

Slide 66 text

11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 66

Slide 67

Slide 67 text

angular.io 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 67

Slide 68

Slide 68 text

Angular ▪ Angular is a framework for building client applications in HTML ▪ TypeScript, JavaScript, Dart ▪ Modules, Components, Templates, Services ▪ Much more… 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 68

Slide 69

Slide 69 text

Modules ▪ Every Angular app has at least one module, the root module ▪ Conventionally named AppModule ▪ A module is a class with an @NgModule decorator 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 69

Slide 70

Slide 70 text

@NgModule ▪ declarations ▪ view classes (components, directives, and pipes) of this module ▪ exports ▪ subset of declarations usable by other modules ▪ imports ▪ exported classes of other modules needed by component templates this module’s templates ▪ providers ▪ creators of services (globally accessible in all parts of the app) ▪ bootstrap ▪ main application view (root component) ▪ Only the root module should set this bootstrap property 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 70

Slide 71

Slide 71 text

Example Module import {NgModule} from '@angular/core'; import {AppComponent} from './app.component'; import {BrowserModule} from '@angular/platform-browser'; import {LocationStrategy, HashLocationStrategy} from '@angular/common'; @NgModule({ declarations: [AppComponent], imports : [BrowserModule], providers : [{ provide: LocationStrategy, useClass: HashLocationStrategy }], bootstrap : [AppComponent] }) export class AppModule {} 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 71

Slide 72

Slide 72 text

Angular Libraries ▪ Angular ships as a collection of Node.js modules ▪ Can be found in node_modules/@angular ▪ common ▪ compiler ▪ core ▪ forms ▪ platform-browser ▪ platform-browser-dynamic ▪ router ▪ … 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 72

Slide 73

Slide 73 text

Launching the App ▪ … by bootstrapping its root module import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; import {AppModule} from './app/app.module'; platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.error(err)); 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 73

Slide 74

Slide 74 text

Components ▪ A component controls a view ▪ In our tutorial, we have 3 components: ▪ AppComponent ▪ UsersComponent ▪ AboutComponent 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 74

Slide 75

Slide 75 text

@Component ▪ Takes configuration to ▪ create and present the component and its view. ▪ A few @Component configuration options: ▪ selector ▪ CSS selector for this component ▪ Here: ▪ Angular renders the templateURl between those tags ▪ templateUrl ▪ address of this component's HTML template ▪ providers ▪ array of dependency injection providers for services that the component requires 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 75

Slide 76

Slide 76 text

Component Example import {Component} from '@angular/core'; import {User} from './user'; import {UsersService} from './users.service'; @Component({ selector: 'app-users', templateUrl: 'app/user/users.component.html', providers: [UsersService], }) export class UsersComponent implements OnInit { private users: User[]; constructor(private usersService: UsersService) { } ngOnInit() { this.users = this.usersService.getUsers(); } } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 76

Slide 77

Slide 77 text

Templates ▪ A component's view is defined by a template ▪ A template looks like regular HTML, but can use Angular specific things 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 77

Slide 78

Slide 78 text

User List Template

Users

{{user.id}} {{user.fullName}} {{user.email}}
11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 78

Slide 79

Slide 79 text

One Way Databinding ▪ Component -> DOM ▪ interpolation: {{user.id}} ▪ Property binding: ▪ ▪ DOM -> Component ▪
  • 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 79
  • Slide 80

    Slide 80 text

    Two Way Databinding ▪ Component <-> DOM ▪ Recommendation: Prefer one way databinding, since it makes control flows easier to understand 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 80

    Slide 81

    Slide 81 text

    Dependency Injection ▪ Used everywhere in Angular ▪ injector is the main mechanism ▪ An injector maintains a container of service instances ▪ service instances are created automatically by the injector ▪ An injector can create a new service instance from a provider ▪ A provider is a recipe for creating a service ▪ Register providers with injectors ▪ Either in modules ▪ Or in components 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 81

    Slide 82

    Slide 82 text

    Services ▪ Are POTOs (Plain Old Typescript Objects) ▪ Should encapsulate functionality that can be uses by ▪ Other services ▪ Components 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 82

    Slide 83

    Slide 83 text

    Example Service import {Injectable} from '@angular/core'; import {User} from './user'; @Injectable() export class UsersService { public getUsers(): User[] { return [ new User('toedter_k', 'Kai Toedter', '[email protected]'), new User('doe_jo', 'John Doe', '[email protected]'), new User('doe_ja', 'Jane Doe', '[email protected]') ]; } } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 83

    Slide 84

    Slide 84 text

    @Injectable ▪ Needed by services, that want to have other services injected ▪ Recommendation: Use it for every service, even if it would not be necessary. Why? ▪ Future proofing: No need to remember @Injectable() when you add a dependency later ▪ Consistency: All services follow the same rules, and you don't have to wonder why a decorator is missing 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 84

    Slide 85

    Slide 85 text

    Singleton Service ▪ Best practice since Angular 6 ▪ Then you don’t have to specify a provider explicitly @Injectable({ providedIn: 'root' }) export class UsersService { // … } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 85

    Slide 86

    Slide 86 text

    Routing ▪ Tell the router how to compose navigation URLs, set base in index.html, e.g., ▪ Import RouterModule and Routes in TypeScript ▪ Create a router configuration ▪ Use tag to display routed components 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 86

    Slide 87

    Slide 87 text

    Router Configuration import { Routes } from '@angular/router'; import {UsersComponent} from './user/users.component'; import {AboutComponent} from './about/about.component'; export const routerConfig: Routes = [ { path: '', redirectTo: 'users', pathMatch: 'full' }, { path: 'users', component: UsersComponent }, { path: 'about', component: AboutComponent } ]; 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 87

    Slide 88

    Slide 88 text

    Routing HTML 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 88

    Slide 89

    Slide 89 text

    Angular CLI ▪ Installation: npm install -g @angular/cli ▪ Create a new project and run it: ng new cd ng serve ▪ Create new component: ng g component 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 89

    Slide 90

    Slide 90 text

    Live Demo 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 90

    Slide 91

    Slide 91 text

    Lab 4: Task 1 ▪ Open terminal in lab4/complete ▪ Invoke: npm start ▪ builds everything using Angular CLI ▪ Starts a Web server at port 4200 ▪ Open http://localhost:4200 in a web browser ▪ You should see the Angular demo app 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 91

    Slide 92

    Slide 92 text

    Lab 4: Task 2 ▪ Work in lab4/initial ▪ Read the README.adoc ▪ Create your own CLI based Angular app 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 92

    Slide 93

    Slide 93 text

    Building the Angular App 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 93

    Slide 94

    Slide 94 text

    Angular & TypeScript ▪ Angular is written itself in TypeScript ▪ Angular brings its own type definitions ▪ TypeScript is the recommended language to write Angular apps ▪ But you could also use JavaScript or Dart 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 94

    Slide 95

    Slide 95 text

    Angular App with no Styling 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 95

    Slide 96

    Slide 96 text

    Lab 5: Task 1 ▪ Open terminal in lab5/complete ▪ Invoke: npm start ▪ builds everything using the Angular CLI ▪ Starts a Web server at port 4200 ▪ Open http://localhost:4200 in a web browser ▪ You should see the web app with no styling ▪ Play around with it 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 96

    Slide 97

    Slide 97 text

    Lab 5: Task 2 ▪ Work in lab5/initial ▪ Implement a small Angular app that displays a list of users and an “About” screen ▪ Add decorators, constructor and method ngOnInit in user.component.ts ▪ Add Angular markup (*ngFor etc.) in user.component.html ▪ Add routing in app.component.html 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 97

    Slide 98

    Slide 98 text

    Bootstrap ▪ www.getbootstrap.com 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 98

    Slide 99

    Slide 99 text

    Bootstrap Summary ▪ By Twitter ▪ HTML, CSS3, JavaScript ▪ Templates ▪ Easy to use ▪ Mobile first 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 99

    Slide 100

    Slide 100 text

    Bootstrap Live Demo 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 100

    Slide 101

    Slide 101 text

    Basic Template 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 101 Hello, world!

    Hello, world!

    Slide 102

    Slide 102 text

    app.component.html 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 102

    Slide 103

    Slide 103 text

    user.component.html

    Users

    … 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 103

    Slide 104

    Slide 104 text

    Bootstrapped Tutorial Web App 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 104

    Slide 105

    Slide 105 text

    Lab 6: Task 1 ▪ Open terminal in lab6/complete ▪ Invoke: npm start ▪ builds everything using the Angular CLI ▪ Starts a Web server at port 4200 ▪ Open http://localhost:4200 in a web browser ▪ You should see the web app with Bootstrap styling ▪ Play around with it 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 105

    Slide 106

    Slide 106 text

    Lab 6: Task 2 ▪ Work in lab6/initial ▪ Enhance index.html ▪ Use slate.css for a dark Bootstrap theme ▪ Add bootstrap css classes to ▪ app.component.html ▪ user.component.html ▪ about.component.html 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 106

    Slide 107

    Slide 107 text

    11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 107 Putting it all together

    Slide 108

    Slide 108 text

    Cross-Origin Resource Sharing (CORS) From Wikipedia: Cross-origin resource sharing (CORS) is a mechanism that enables many resources (e.g. fonts, JavaScript, etc.) on a web page to be requested from another domain outside the domain from which the resource originated.[ 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 108

    Slide 109

    Slide 109 text

    CORS with Angular CLI ▪ Provide a file proxy.conf.json { "/api": { "target": "http://localhost:8080", "secure": false } } ▪ Change npm start script: "start": "ng serve --proxy-config proxy.conf.json", 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 109

    Slide 110

    Slide 110 text

    Angular HTTP ▪ The HTTP service uses Observables from rxjs ▪ The user service now makes an asynchronous call to the REST backend and returns an Observable ▪ The user component subscribes for changes and updates its own view model 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 110

    Slide 111

    Slide 111 text

    User Service with HTTP @Injectable() export class UsersService { constructor(private http: HttpClient) {} public getUsers(): Observable { const uri = '/api/users'; return this.http.get(uri).pipe( map((response: any) => response._embedded['users']), catchError(this.handleError)); } … 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 111

    Slide 112

    Slide 112 text

    UsersComponent with Subscription export class UsersComponent { private users: User[]; constructor(private usersService: UsersService) {} ngOnInit() { this.usersService.getUsers() .subscribe( (users: User[]) => this.users = users, error => console.error( 'UsersComponent: cannot get users')); } } 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 112

    Slide 113

    Slide 113 text

    Live Demo 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 113

    Slide 114

    Slide 114 text

    Lab 7: Task 1 ▪ Start the Spring Boot app from lab7 ▪ Open terminal in lab7/complete ▪ Invoke: npm start ▪ builds everything using the Angular CLI ▪ Starts a Web server at port 4200 ▪ Open http://localhost:4200 in a web browser ▪ You should see the web app ▪ The user list is served by the backend service 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 114

    Slide 115

    Slide 115 text

    Lab 7: Task 2 ▪ Implement the user service using HTTP ▪ Implement the users component with subscription 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 115

    Slide 116

    Slide 116 text

    Final Application 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 116

    Slide 117

    Slide 117 text

    11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 117

    Slide 118

    Slide 118 text

    11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 118 Discussion

    Slide 119

    Slide 119 text

    License ▪ This work is licensed under a Creative Commons Attribution 4.0 International License. ▪ See http://creativecommons.org/licenses/by/4.0/ 11/11/2022 © Kai Tödter, Licensed under a Creative Commons Attribution 4.0 International License. 119