Skip to content

Latest commit

 

History

History
328 lines (249 loc) · 13.3 KB

03-getting-started-customers-app.md

File metadata and controls

328 lines (249 loc) · 13.3 KB

SCION Microfrontend Platform

SCION Microfrontend Platform Projects Overview Changelog Contributing Sponsoring

SCION Microfrontend Platform > Getting Started > Create Customers Application

The customers micro app provides two microfrontends, the CustomerList Microfrontend that lists our customers, and the Customer Microfrontend that displays a customer.


  • Project directory:
    scion-microfrontend-platform-getting-started/customers-app
  • Installing modules (if not already done):
    npm run install
  • Starting the app:
    npm run start
  • Opening the app in the browser:
    http://localhost:4202

Prerequisites

If you checked out the skeleton branch of the Git repository for this guide, the directory structure should look like this. If not, please refer to How to complete this guide for step-by-step instructions.

   scion-microfrontend-platform-getting-started
   ├── customers-app
   │   ├── src
   │   │   ├── customer // Customer Microfrontend
   │   │   │    ├── customer.html
   │   │   │    ├── customer.ts
   │   │   │    └── customer.scss
   │   │   ├── customer-list  // CustomerList Microfrontend
   │   │   │    ├── customer-list.html
   │   │   │    ├── customer-list.ts
   │   │   │    └── customer-list.scss
   │   │   ├── index.html
   │   │   ├── customer.data.json // Sample data
   │   │   ├── customer.service.ts // Service to access sample data
   │   │   └── query-params.ts
   │   ├── package.json
   │   └── tsconfig.json

Follow the following instructions to get the Customers App running.

Start the *Customers App*

Run npm run start to start the application. Then open the page http://localhost:4202 in your browser. You should see two links to open the CustomerList Microfrontend and Customer Microfrontend. When you click on a link, the particular microfrontend opens, but does not show much yet, only its title.

By the end of this chapter, the CustomerList Microfrontend will list our customers. When clicking on a customer link, we can navigate to the Customer Microfrontend to see details about the customer.

Implement the *CustomerList Microfrontend*

In this section, we will implement the CustomerList Microfrontend that lists our customers.

  1. Open the HTML template customers-app/src/customer-list/customer-list.html.

  2. After the <h1> element, add a section to display our customers, as follows:

          <body>
            <h1>Customers</h1>
    [+]     <section id="customers"></section>
          </body> 
  3. Open the TypeScript file customers-app/src/customer-list/customer-list.ts and add the following method after the init method. This method will render all our customers.

          import {CustomerService} from '../customer.service';
    
          public render(): void {
            const customersSection = document.querySelector('section#customers');
          
            CustomerService.INSTANCE.getCustomers().forEach(customer => {
              // Customer Link
              const customerLink = customersSection.appendChild(document.createElement('a'));
              customerLink.innerText = `${customer.firstname} ${customer.lastname}`;
              customerLink.href = `/customer/customer.html#?id=${customer.id}`;
          
              // City
              customersSection.appendChild(document.createTextNode(customer.city));
            });
          }

    We need a reference to the <section> element that we added to the template in the previous step. Our customers will be added to this section. Using the CustomerService, we query our customers. For each customer, we create an anchor element, that when clicked, navigates to the Customer Microfrontend located at /customer/customer.html. We pass the ID of the customer in the form of a query parameter. Note that we added the query parameter to the URL's fragment part, that is after the hash (#), so that the page is not reloaded when the query parameter is changed. This is similar to hash-based routing, but it only applies to query parameters. Finally, after the link, we append a text node to display the city of the customer.

  4. In the init method, simply call render.

          public async init(): Promise<void> {
    [+]     this.render();
          }
Implement the *Customer Microfrontend*

In this section, we will implement the Customer Microfrontend to display a customer.

  1. Open the HTML template customers-app/src/customer/customer.html.

  2. After the <h1> element, add a section to display the customer, as follows:

          <body>
            <h1>Customer</h1>
    [+]     <section id="customer"></section>
          </body> 
  3. Open the TypeScript file customers-app/src/customer/customer.ts.

    Add a render method after the init method to render the customer of given ID, as follows:

          import {CustomerService} from '../customer.service';
    
          public render(customerId: string): void {
            const customerSection = document.querySelector('section#customer');
            const customer = CustomerService.INSTANCE.getCustomer(customerId);
    
            customerSection.innerHTML = null;
    
            // Firstname
            customerSection.appendChild(document.createElement('label')).innerText = 'Firstname:';
            customerSection.appendChild(document.createTextNode(customer.firstname));
    
            // Lastname
            customerSection.appendChild(document.createElement('label')).innerText = 'Lastname:';
            customerSection.appendChild(document.createTextNode(customer.lastname));
    
            // Street
            customerSection.appendChild(document.createElement('label')).innerText = 'Street:';
            customerSection.appendChild(document.createTextNode(customer.street));
    
            // City
            customerSection.appendChild(document.createElement('label')).innerText = 'City:';
            customerSection.appendChild(document.createTextNode(customer.city));
    
            // Email
            customerSection.appendChild(document.createElement('label')).innerText = 'Email:';
            customerSection.appendChild(document.createTextNode(customer.email));
    
            // Phone
            customerSection.appendChild(document.createElement('label')).innerText = 'Phone:';
            customerSection.appendChild(document.createTextNode(customer.phone));
          }

    We need a reference to the <section> element that we added to the template in the previous step. The customer will be added to this section. Since the render method is called every time the customer to be displayed change, we clear the section's content first. Finally, using the CustomerService, we look up the customer of given ID and display its firstname, lastname, street, city, email and phone.

  4. In the init method, subscribe to query parameter changes and invoke the render method, passing the id as argument. The id query parameter contains the ID of the customer to be displayed.

          import {CustomerService} from '../customer.service';
    [+]   import {QueryParams} from '../query-params';
    
          public async init(): Promise<void> {
    [+]     QueryParams.observe$.subscribe(queryParams => this.render(queryParams.get('id')));
          }
Open the app in the browser

We did it! Run npm run start to serve the applications.

When you open the page http://localhost:4200 in your browser and click the Customers button, you will see the CustomerList Microfrontend. When clicking on a customer, the Customer Microfrontend opens, displaying information about the customer. So far, the Customer Microfrontend replaces the CustomerList Microfrontend. In a subsequent chapter, we will display the customer to the right of the customer list in the aside router outlet.

What we did in this chapter

In this chapter, we have implemented the CustomerList Microfrontend and Customer Microfrontend of the Customers App.

The customers-app/src/customer-list/customer-list.html looks as following:
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Customers</title>
    <link rel="stylesheet" type="text/css" href="customer-list.scss">
    <script type="module" src="./customer-list.ts"></script>
  </head>
  <body>
    <h1>Customers</h1>
    <section id="customers"></section>
  </body>
</html>
The customers-app/src/customer-list/customer-list.ts looks as following:
import {CustomerService} from '../customer.service';

class CustomerListController {

  public async init(): Promise<void> {
    this.render();
  }

  public render(): void {
    const customersSection = document.querySelector('section#customers');

    CustomerService.INSTANCE.getCustomers().forEach(customer => {
      // Customer Link
      const customerLink = customersSection.appendChild(document.createElement('a'));
      customerLink.innerText = `${customer.firstname} ${customer.lastname}`;
      customerLink.href = `/customer/customer.html#?id=${customer.id}`;

      // City
      customersSection.appendChild(document.createTextNode(customer.city));
    });
  }
}

new CustomerListController().init();
The customers-app/src/customer/customer.html looks as following:
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Customer</title>
    <link rel="stylesheet" type="text/css" href="customer.scss">
    <script type="module" src="./customer.ts"></script>
  </head>
  <body>
    <h1>Customer</h1>
    <section id="customer"></section>
  </body>
</html>
The customers-app/src/customer/customer.ts looks as following:
import {CustomerService} from '../customer.service';
import {QueryParams} from '../query-params';

class CustomerController {

  public async init(): Promise<void> {
    QueryParams.observe$.subscribe(queryParams => this.render(queryParams.get('id')));
  }

  public render(customerId: string): void {
    const customerSection = document.querySelector('section#customer');
    const customer = CustomerService.INSTANCE.getCustomer(customerId);

    customerSection.innerHTML = null;

    // Firstname
    customerSection.appendChild(document.createElement('label')).innerText = 'Firstname:';
    customerSection.appendChild(document.createTextNode(customer.firstname));

    // Lastname
    customerSection.appendChild(document.createElement('label')).innerText = 'Lastname:';
    customerSection.appendChild(document.createTextNode(customer.lastname));

    // Street
    customerSection.appendChild(document.createElement('label')).innerText = 'Street:';
    customerSection.appendChild(document.createTextNode(customer.street));

    // City
    customerSection.appendChild(document.createElement('label')).innerText = 'City:';
    customerSection.appendChild(document.createTextNode(customer.city));

    // Email
    customerSection.appendChild(document.createElement('label')).innerText = 'Email:';
    customerSection.appendChild(document.createTextNode(customer.email));

    // Phone
    customerSection.appendChild(document.createElement('label')).innerText = 'Phone:';
    customerSection.appendChild(document.createTextNode(customer.phone));
  }
}

new CustomerController().init();
What's next

In the next chapter, we will learn how to use the outlet router for microfrontend navigation. Click here to continue.