ANGULAR 2 和 EXPRESS

The last part is to connect the Angular app to the express server. To do this, we'll need to make some modifications to our angular 2 app to consume the express api.

mean-docker/angular-client/src/app/app.component.ts

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';

// Import rxjs map operator
import 'rxjs/add/operator/map';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'app works!';

  // Link to our api, pointing to localhost
  API = 'http://localhost:3000';

  // Declare empty list of people
  people: any[] = [];

  constructor(private http: Http) {}

  // Angular 2 Life Cycle event when component has been initialized
  ngOnInit() {
    this.getAllPeople();
  }

  // Add one person to the API
  addPerson(name, age) {
    this.http.post(`${this.API}/users`, {name, age})
      .map(res => res.json())
      .subscribe(() => {
        this.getAllPeople();
      })
  }

  // Get all users from the API
  getAllPeople() {
    this.http.get(`${this.API}/users`)
      .map(res => res.json())
      .subscribe(people => {
        console.log(people)
        this.people = people
      })
  }
}

Angular 2 style guides usually recommends separating most logic into a service/provider. We've placed all the code in the component here for brevity.

We've imported theOnInitinterface, to call events when the component is initialized, then added a two methodsAddPersonandgetAllPeople, that call the API.

Notice that this time round, ourAPIis pointing tolocalhost. This is because while the angular 2 app will be running inside the container, it's served to the browser. And the browser is the one that makes request. It will thus make a request to the exposed express API. As a result, we don't need to link Angular and Express in thedocker-compose.ymlfile.

Next, we need to make some changes to the template. I first added bootstrap via cdn to theindex.html

mean-docker/angular-client/src/app/index.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Angular Client</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">

  <!-- Bootstrap CDN -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css">

  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root>Loading...</app-root>
</body>
</html>

Then update the app.component.html template

mean-docker/angular-client/src/app/app.component.html

<!-- Bootstrap Navbar -->
<nav class="navbar navbar-light bg-faded">
  <div class="container">
    <a class="navbar-brand" href="#">Mean Docker</a>
  </div>
</nav>

<div class="container">
  <div [style.margin-top.px]="10" class="row">
    <h3>Add new person</h3>
    <form class="form-inline">
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name" #name>
      </div>
      <div class="form-group">
        <label for="age">Age</label>
        <input type="number" class="form-control" id="age" #age>
      </div>
      <button type="button" (click)="addPerson(name.value, age.value)" class="btn btn-primary">Add person</button>
    </form>
  </div>
  <div [style.margin-top.px]="10" class="row">
    <h3>People</h3>
    <!-- Bootstrap Card -->
    <div [style.margin-right.px]="10" class="card card-block col-md-3" *ngFor="let person of people">
      <h4 class="card-title">{{person.name}}  {{person.age}}</h4>
    </div>
  </div>
</div>

The above template shows the components properties and bindings. We are almost done.

Since we've made changes to our code, we need to do a build for our Docker Compose

$ docker-compose up --build

The--buildflag tells docker compose that we've made changes and it needs to do a clean build of our images.

Once this is done, go tolocalhost:4200in your browser,

We are getting aNo 'Access-Control-Allow-Origin'error. To quickly fix this, we need to enable Cross-Origin in our express app. We'll do this with a simple middleware.

mean-docker/express-server/server.js

// Code commented out for brevity

// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// Cross Origin middleware
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*")
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
  next()
})

// Set our api routes
app.use('/', api);

// Code commented out for brevity

We can now run docker-compose again with the build flag. You should be in themean-docker directory

$ docker-compose up --build

Going tolocalhost:4200on the browser.

results matching ""

    No results matching ""