$30 off During Our Annual Pro Sale. View Details »

Modern Web Apps with Spring Boot & Angular

Kai Toedter
November 11, 2022

Modern Web Apps with Spring Boot & Angular

This is the slide deck for my training "Modern Web Apps with Spring Boot & Angular". You find more information in English and German at http://toedter.com/cool-web-apps-training/. This slide deck is licensed under a Creative Commons Attribution 4.0 International License.

Kai Toedter

November 11, 2022
Tweet

More Decks by Kai Toedter

Other Decks in Programming

Transcript

  1. 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.

    View Slide

  2. 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.

    View Slide

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

    View Slide

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

    View Slide

  5. 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

    View Slide

  6. 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.

    View Slide

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

    View Slide

  8. 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.

    View Slide

  9. 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

    View Slide

  10. 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

    View Slide

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

    View Slide

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

    View Slide

  13. 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

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

  16. 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

    View Slide

  17. 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

    View Slide

  18. 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

    View Slide

  19. 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

    View Slide

  20. 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

    View Slide

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

    View Slide

  22. 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.

    View Slide

  23. 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

    View Slide

  24. 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

    View Slide

  25. 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

    View Slide

  26. 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

    View Slide

  27. 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

    View Slide

  28. 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

    View Slide

  29. 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

    View Slide

  30. 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

    View Slide

  31. 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

    View Slide

  32. 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

    View Slide

  33. 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

    View Slide

  34. 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

    View Slide

  35. 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

    View Slide

  36. 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

    View Slide

  37. 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

    View Slide

  38. 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

    View Slide

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

    View Slide

  40. 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

    View Slide

  41. 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

    View Slide

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

    View Slide

  43. 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.

    View Slide

  44. 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

    View Slide

  45. 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

    View Slide

  46. 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

    View Slide

  47. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  51. 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

    View Slide

  52. 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

    View Slide

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

    View Slide

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

    View Slide

  55. 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

    View Slide

  56. 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

    View Slide

  57. 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

    View Slide

  58. 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

    View Slide

  59. 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

    View Slide

  60. 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

    View Slide

  61. @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

    View Slide

  62. 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

    View Slide

  63. 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

    View Slide

  64. 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

    View Slide

  65. 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

    View Slide

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

    View Slide

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

    View Slide

  68. 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

    View Slide

  69. 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

    View Slide

  70. @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

    View Slide

  71. 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

    View Slide

  72. 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

    View Slide

  73. 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

    View Slide

  74. 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

    View Slide

  75. @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

    View Slide

  76. 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

    View Slide

  77. 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

    View Slide

  78. 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

    View Slide

  79. 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

    View Slide

  80. 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

    View Slide

  81. 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

    View Slide

  82. 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

    View Slide

  83. 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

    View Slide

  84. @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

    View Slide

  85. 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

    View Slide

  86. 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

    View Slide

  87. 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

    View Slide

  88. Routing HTML


    About
    Users



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

    View Slide

  89. 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

    View Slide

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

    View Slide

  91. 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

    View Slide

  92. 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

    View Slide

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

    View Slide

  94. 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

    View Slide

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

    View Slide

  96. 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

    View Slide

  97. 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

    View Slide

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

    View Slide

  99. 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

    View Slide

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

    View Slide

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








    Hello, world!


    Hello, world!



    View Slide

  102. app.component.html



    Webapp Tutorial


    Users
    About






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

    View Slide

  103. user.component.html

    Users


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

    View Slide

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

    View Slide

  105. 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

    View Slide

  106. 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

    View Slide

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

    View Slide

  108. 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

    View Slide

  109. 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

    View Slide

  110. 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

    View Slide

  111. 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

    View Slide

  112. 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

    View Slide

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

    View Slide

  114. 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

    View Slide

  115. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  119. 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

    View Slide