Angular Example: Coffee Ordering

This is the final version of our Angular example. It allows the user to input their coffee orders, saves them to a list of orders in our controller, then sends those orders to the backend (PHP) for processing.

Please consider this as an example and a start: the details of processing the data and handling the responses have been left up to you.

Angular index.html

<!doctype html>
<html lang="en">
  <meta charset="utf-8">
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link href="" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

Angular Root Module

Root Module Definition: app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { FeedbackModule } from './feedback/feedback.module';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { OrdersComponent } from './orders/orders.component';
import { NavbarComponent } from './navbar/navbar.component';

  declarations: [
  imports: [
  providers: [],
  bootstrap: [AppComponent]
export class AppModule { }

Root Component Controller: app.component.ts

import { Component } from '@angular/core';

  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
export class AppComponent {
  title = 'Orders Up';
  author = "Robbie";

Root Component View: app.component.html

<!-- NAVBAR -->

<div class="container">
    <div class="row">
        <div class="col-md-8">
            <p>By: </p>
        <div class="col-md-4">

Drink Model (Class): drink.ts

export class Drink {
        public description: string,
        public size: string,
        public temp: string,
        public name: string,
        public email: string) {}

Orders Component Controller: orders/orders.component.ts

import { Component, OnInit } from '@angular/core';
import { Drink } from '../drink';
import { OrderService } from '../order.service';

  selector: 'app-orders',
  templateUrl: './orders.component.html',
  styleUrls: ['./orders.component.css']
export class OrdersComponent implements OnInit {

  coffee: string;
  drink: Drink;
  sizes: Array<string> = ["small", "medium", "large"];
  temps: Array<string> = ["hot", "cold"];
  orders: Array<Drink> = [];
  placeMsg: string;

  constructor( private orderService: OrderService ) { = "Peppermint Mocha";
    this.placeMsg = "";
    this.drink = new Drink("", "", "", "", "");
  placeOrder(): void {
    this.placeMsg = "Thank you, " + + ".";
    this.placeMsg += "You ordered a " + this.drink.description + ", size"
                        + this.drink.size + ".";
  submitForm(data: any):void {
     let dr = new Drink(data.description, data.size, data.temp,
  response: any;
  orderTime: string = "";
  sendOrder(): void {
        (respData) =>  { 
            this.response = respData; 
            this.orderTime = respData.time; 
        (error) => { console.log("Error: ", error); }

  ngOnInit(): void {

Orders Component View: orders/orders.component.html

<p>Coffee: </p>

<p>Drink Desc: </p>

<p>Drink Model: </p>

<form #orderForm="ngForm" (ngSubmit)="submitForm(orderForm.value)">
    <div class="mb-3">
        <label for="description" class="form-label">Drink Description</label>
        <input [(ngModel)]="drink.description"
            type="text" class="form-control" name="description" placeholder="ex: Pumpkin Spice Latte"/>
    <div class="mb-3">
        <label for="size" class="form-label">Size</label>
        <select [(ngModel)]="drink.size"
                class="form-select" name="size">
            <option *ngFor="let size of sizes"></option>
    <div class="mb-3">
        <label for="temp" class="form-label">Temperature</label>
        <select [(ngModel)]="drink.temp"
                class="form-select" name="temp">
            <option *ngFor="let temp of temps"></option>
    <div class="mb-3">
        <label for="name" class="form-label">Name</label>
        <input [(ngModel)]=""
            minlength="4" maxlength="100"
            [] = "name.invalid && name.touched"
            type="text" class="form-control" name="name"/>
        <small class="text-danger" 
                [class.d-none]= "name.valid || name.untouched">
                Name is required</small>
    <div class="mb-3">
        <label for="email" class="form-label">Email</label>
        <input [(ngModel)]=""
            [] = "email.invalid && email.touched"
            type="email" class="form-control" name="email" placeholder="Your contact email"/>        
        <small class="text-danger" 
                [class.d-none]= "email.valid || email.untouched">
                Email is required</small>
    <div class="mb-3">
        <button class="btn btn-primary" 
            Add Item

<p>Description from form: </p>

<p>Entire form: </p>

<p style="color: blue;"></p>


<h4>Your Orders</h4>


<table class="table">
        <tr *ngFor="let order of orders">

<div class="mb-3">
    <button class="btn btn-success" 
        [disabled]="orders.length == 0"
        Send Order


<p> PHP Response:  </p>

<p> Order time:  </p>
import { Component, OnInit } from '@angular/core';

  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
export class NavbarComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container">
    <a class="navbar-brand" href="#">Orders Up</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav me-auto mb-2 mb-lg-0">
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" href="#">Home</a>
        <li class="nav-item">
          <a class="nav-link" href="#">Prices</a>

Feedback Module

Feedback Module Definition: feedback/feedback.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ContactComponent } from './contact/contact.component';

  declarations: [
  imports: [
  ], exports: [
export class FeedbackModule { }

Contact Component Controller: feedback/contact/contact.component.ts

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

  selector: 'app-contact',
  templateUrl: './contact.component.html',
  styleUrls: ['./contact.component.css']
export class ContactComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {


Contact Component View: feedback/contact/contact.component.html

<p>contact works!</p>

PHP Back-End Code


// Allow access to our development server, localhost:4200
header("Access-Control-Allow-Origin: http://localhost:4200");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT");

$request = file_get_contents("php://input");
$data = json_decode($request, true);

// Do processing of the data

$output = [
    "time" => date("Y-m-d g:i a"),
    "request" => $data

$drinks = [];

foreach ($data as $drink) {
    array_push($drinks, "{$drink["description"]} for {$drink["name"]}");

$output["drinks"] = $drinks;

// Send the result to the client (print it out)

header("Content-Type: application/json");
echo json_encode($output, JSON_PRETTY_PRINT);