Activity: Get started with Angular

(no submission)

Purpose:

You may work alone or with another student in this course.

To deploy and test your program, please refer to Angular deployment.


For this activity, we may use your solution from the First Angular app (module and component) activity or create a new Angular app.

Task #:1 Work with a data model (i.e., class)

  1. Generate a class named friend
    ng generate class friend

  2. Open friend.ts class, add the following code representing a data model of a friend object
    export class Friend {
       name: string;
       email: string;
       age: number;
    
       constructor(name: string, email: string, age: number) {
          this.name = name;
          this.email = email;
          this.age = age;
       } 
    } 
    Now, the Friend class is made available.

  3. Since a Friend class will be used as a data model in a FriendsComponent, the Friend class must be imported into the FriendsComponents. Go to the src/app/friends/ folder, open friends.component.ts component. Include the following code to specify the dependency
    import { Friend } from '../friend'; 
    Note that, in the previous step, a Friend class was described in friend.ts. Be sure to specify the path to friend.ts properly. Do not include the extension. In this example, since friend.ts was created outside of friends (folder) component, ../friend instructs the compiler to go out one folder to find the targeted file. (If friend.ts was created in the friends folder, use ./friend instead)

    Define a property friend to be of type Friend and initial it with some name and email address.
    export class FriendsComponent implements OnInit {
      friendname: string;    // from previous activity
      friend: Friend;
    
      constructor() {
        this.friendname = 'somename';    // from previous activity
        this.friend = new Friend( 'Humpty', 'humpty@uva.edu', 20 );
      }
    
      ngOnInit(): void {
      }
    
    }

  4. Display the friend object. Go to the src/app/friends/ folder, open friends.component.html template. Add the following code to bind data from the model to the template.
    Hello {{ friendname }} 
    <p>Friend's information:
      name ={{ friend.name }},
      email = {{ friend.email }}, 
      age = {{ friend.age }} </p> 

  5. Display the friend object in a JSON format. Open friends.component.html template, add the following code to bind data from the model to the template and format the data.
    <p>{{ friend | json }} </p>

  6. Format the data with the UppercasePipe and the LowercasePipe. Open friends.component.html template, add the following code
    <p>{{ friend.name | uppercase }}</p>
    <p>{{ friend.name | lowercase }}</p>

  7. Style a content with style binding. Open friends.component.html template, add the following code
    <p [style.color]="'green'">Are you hungry?</p>

  8. Let's try an ngIf directive. Open friends.component.html template, add the following code
    <div *ngIf="friend.name=='Humpty'">What's up Humpty?</div>

  9. Let's try an ngFor directive. Open friends.component.ts, add the following code in the export code block
    manyfriends = [
       { name: 'Mickey', email: 'mickey@uva.edu', age: 30 },
       { name: 'Minnie', email: 'minnie@uva.edu', age: 40 },
       { name: 'duh', email: 'duh@uva.edu', age: 50 },
       { name: 'huh', email: 'huh@uva.edu', age: 60 }
      ];  
    Open friends.component.html template, add the following code
    <h4>List of many friends</h4>
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Email</th>
          <th>Age</th>
        </tr>
      </thead>
      <tr *ngFor="let myfriend of manyfriends">
        <td>{{ myfriend.name }}</td>
        <td>{{ myfriend.email }}</td>
        <td>{{ myfriend.age }}</td>
      </tr>
    </table>

Task #2: More data binding and directives

  1. Inject a FormsModule into the project by importing it into the root module.
    import { FormsModule } from '@angular/forms';

    Then, include FormsModule in the imports array to make it available to every component in the root module.
    imports: [
        BrowserModule,
        FormsModule
    ] 

  2. In friends.component.html, create a form allowing a user to enter his/her friend's name and email address. You may use the following code or create your own form.
    <form>
       <div class="form-group">
          <label for="friendname">Friend name:</label>
          <input type="text" class="form-control" name="friendname" />
       </div>
       <div class="form-group">
          <label for="email">Email:</label>
          <input type="email" class="form-control" name="email" />
       </div>
       <div class="form-group">
          <label for="age">Age:</label>
          <input type="number" class="form-control" name="age" />
       </div>
    </form>

  3. Attach a template reference to the <form> tag and assign an ngForm directive to it.
    <form #infoForm="ngForm">

  4. Include ngModel such that the input's value can be accessed through the template reference.
    <input ngModel type="text" class="form-control" name="friendname" />
    Also include ngModel for the email and age inputs.

  5. Retrieve the form inputs and display them on the screen, using string interpolation
    <p><b>Retrieve values from the form: </b> <br/>
       {{ infoForm.value | json }}  <br/>
       {{ infoForm.value.friendname }} <br/> 
       {{ infoForm.value.email }}  <br/>
       {{ infoForm.value.age }}
    </p> 
    Note: asynchronous behavior vs. synchronous behavior

  6. Use property binding to bind the data model to the view. In the friends.component.ts, a friend instance was created and initialized previously. Let's bind the information saved in the friend instance (data model) to the form input boxes (view).
    <input [ngModel]="friend.name" type="text" class="form-control" name="friendname" />
    Also do property binding for the email and age inputs.

  7. Retrieve the values from the friend model instance and display them on the screen
    <p><b>Retrieve values from the model:</b> <br/>
       {{ friend.name }} <br/> 
       {{ friend.email }} <br/>
       {{ friend.age }}
    </p> 

  8. Use two-way binding to bind between view and model.
    <input [(ngModel)]="friend.name" type="text" class="form-control" name="friendname" />
    Also do two-binding for the email input.

  9. Let's change the value of the name when the button is clicked.

    In friends.component.ts, write a function named changeDefaultName that takes a string and then updates the friend's name with the given string.

    changeDefaultName(str: string) {
         this.friend.name = str;
    }
    Use event binding to bind a click event to a submit button.
    <button (click)="changeDefaultName('someone')" class="btn btn-primary">Click to change the name</button>

Task #3: Multiple modules [optional]

Imagine, you are developing a project that involves multiple modules. Suppose one of your modules deals with some forms of feedback (e.g., users' comment through a contact us form or votes such as like or dislike).

  1. Create a module named feedback
    ng generate module feedback

  2. Go inside the feedback directory, create a contact component
    ng generate component contact

  3. Modify the view of the contact component such that it contains a contact us form. You may use the following code or create your own form.
    <form>
       <div class="form-group">
          <label for="name">Your name (optional):</label>
          <input type="text" class="form-control" name="name" />
       </div>
       <div class="form-group">
          <label for="comment">Comment:</label>
          <textarea class="form-control" name="comment" required></textarea>
       </div>
       <div>
          <input type="submit" class="btn btn-secondary form-control" value="Send email" />
       </div>
    </form> 

  4. Make the contact component visible in the feedback module. Ensure that contact component is exported from the contact component controller.

  5. Make the contact component visible outside of the feedback module. Modify feedback.module.ts by specifying the contact component in the exports array
    exports: [
        ContactComponent, 
    ] 

  6. Modify the root module controller (app.module.ts) to import the newly created module into the root module.
    import { FeedbackModule } from './feedback/feedback.module';

    Be sure to also include FeedbackModule in the imports array

  7. Add the contact component to the view of the root component (app.component.html)

You may modify your interface the way you like. Get creative. Feel free to add additional elements you feel should be included and have fun!

For more practice, try adding more content. Make use modules, components, classes, as well as data binding and directives.