Home » Advertising » Creating Your First Angular 4 App Using Angular IDE

Creating Your First Angular 4 App Using Angular IDE

Some time ago, an article called Creating My First Web App with Angular 2 in Eclipse was published. Since then, Angular was upgraded and became Angular 4, and new tooling for it in Webclipse appeared. Let’s see how to create a simple application using Angular 4 and new Angular tooling looks.

Pre-Requisites

  • Angular IDE or Webclipse —We’ll do our development using this Eclipse-based IDE. If you want to go without it – please, refer to the previous article.
  • Node.js, NPM, Angular CLI—These are the core tools for Angular development. They would be installed automatically by the IDE.
  • Basic knowledge of TypeScript, HTML, and Eclipse.

Creating a New Angular Project

Switch to Angular perspective using the button at the top-right corner of your IDE.

switch-to-angular-perspective

Right-click the empty area in Project Explorer/Project Explorer+, and choose New Angular Project:

project-explorer-new-angular-project

You’ll see the new Angular project wizard, where you can select the Node.js, NPM, and Angular CLI versions you want to use. For now, let’s enter our project name, “vehicles,” and leave all versions as default.

new-angular-project-wizard

After that, you can either click “Finish” or “Next” and see a list of the commands which would be executed in the local terminal to create your project.

In the Terminal+ view, you can see how commands are executed while creating your project. Also, Terminal+ is used while performing any Angular CLI commands – for creating new elements, starting a server, etc. You can use it for entering your own commands as well.

terminal-view

Creating Model Classes and Elements

We’ll create a simple master-details view application, like the one in the previous example. Let’s start. Right-click the newly created project, expand it, expand the src/app folder, create the folder model inside the src/app folder, right-click it, and choose New Typescript Class. Enter “Vehicle” into the “Name” field.

new-ts-class

Make a newly created Vehicle class by using the following TypeScript code:

export class Vehicle {
  id;
  name;
  type;
  mass;
}

Right-click the app folder again, and choose New Component:

new-component

In the newly opened wizard, enter element the name as vehicle-list:

vehicle-list
A Vehicle-list.component.ts file will open. It contains the basic component’s infrastructure, which should look like the following:

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

@Component({
  selector: 'app-vehicle-list',
  templateUrl: './vehicle-list.component.html',
  styleUrls: ['./vehicle-list.component.css']  
})
export class VehicleListComponent implements OnInit {

constructor() { }

  ngOnInit() {
  }

}

All the basic component infrastructures are present here.

  • The first line is importing the Component decorator function and the OnInit interface. This decorator function is describing metadata for any Angular 2 reusable UI component. The OnInit interface extension is used to register an init lifecycle hook (see below).
  • Selector specifies the tag name that would trigger this component’s insertion.
  • TemplateUrl and styleUrls specify the file names that contain an HTML-based template for the component UI and CSS styling for it.
  • Class VehiclesListComponent should contain almost all the inner component logic written in TypeScript. For now, it contains only an empty constructor and empty ngOnInit lifecycle hook. This hook can be useful for some “heavy” initialization like network or database calls. Constructor should be used only for basic initialization, without any heavy IO.

OK, we’ll definitely need to store a list of our vehicles somewhere. Let’s add a field, vehicles: Vehicle[]; to the VehiclesListComponent class. Of course, Vehicle will be highlighted in red—currently, the TS compiler knows nothing about it. To fix this, just put your mouse over the Vehicle class name underlined in red, or put a caret into it and click Ctrl+1. You’ll see the following quick fix suggestion:

vehicle-list-componentClick on the link with the given suggestion and import the statement for Vehicle class (it will be added to the top of the file).

Service

Well, now we have a vehicle list, but how can we interact with it? Passing it to the constructor would make our code less flexible by requiring a concrete list to be specified when creating a vehicle list component. There’s a better solution—Angular supports Dependency Injection out-of-the-box, and it can be accomplished using Angular Services.

Right-click the src folder again, choose New Service. In the opened wizard, enter element name “vehicle,” and press “Finish.” Vehicle.service.ts file would be created in the app folder.

Angular Service is used when some common functionality needs to be provided to several modules. For now, we won’t implement any complex logic to obtain the list and will just hard code our vehicle entries. In the following code, we import the Injectable decorator, set up our list, assign a given list to a class field and return it by demand:

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

const vehicles = [
  {
      id: 1,
      name: 'Trailer - 1',
      type: 'Truck',
      mass: 40
  },
  {
      id: 2,
      name: 'An-2',
      type: 'Plane',
      mass: 5
  },
  {
      id: 3,
      name: 'LandCruiser 80',
      type: 'Jeep',
      mass: 2
  },
];

@Injectable()
export class VehicleService {

  private vehicles;

  constructor() {
    this.vehicles = vehicles;
  }

  getVehicles() {
    return this.vehicles;
  }

}

Now, let’s go back to vehicles-list.component.ts, import VehicleService and make 2 more edits: add providers: [VehicleService] to @Component and change constructor to:

  constructor(private vehicleService: VehicleService) {
    this.vehicles = this.vehicleService.getVehicles();
}

We’re basically done with the component, let’s switch to UI. Open the vehicle-list.component.html and replace its mock contents with our table.

table class="tftable"
  trthID/ththName/ththType/ththMass/th
  tr *ngFor="let vehicle of vehicles"
    td{{vehicle.id}}/td td{{vehicle.name}}/td td{{vehicle.type}}/td td{{vehicle.mass}}/td
  /tr
/table

We do a conceptually simple thing here—create a table with a constant header and then iterate over vehicles list, creating a table row for each vehicle. A row is composed of cells with corresponding properties.

  • *ngFor is a built-in directive iterating over a list (vehicles in our case).
  • {{ }} tells Angular to read a given property from the TypeScript model and render it.

Also, we specify table class here because we want to have some styling for it—corresponding styles are put into vehicles-list.component.css. You can download the sample project and open them if necessary.

Plugging In

Ok, we’re done with our initial UI. To see the result, just add our selector tag to app.component.html:

app-vehicles-list/app-vehicles-list

Then go to Servers view (or open it if necessary), select your newly created project, and click “Start Server.”

serversYou can monitor the startup process in the Terminal+ view. Also, CLI would dispatch changes to project files and rebuild the app immediately after the changes are saved – this process is also reflected in Terminal+.

Open your browser (it’s highly recommended to use Chrome) and type localhost:4200 in its address bar. Here we go, the application works!

vehicle-registry

Master-Details

Our table is pretty, but not very interactive, huh? OK, let’s make it a bit more “dynamic” by adding a Details view that displays a clicked table row and allows the fields to be edited. Let’s create a VehicleDetailsComponent – choose New Component and enter “vehicle-details” as the name.

Just like for Vehicle List, a folder with TS and HTML/CSS files will be created. We’ll need to modify two of them. VehicleDetailsComponent in vehicle-details.component.ts needs to have a field for the current vehicle—vehicle:Vehicle, with the @Input directive above. This decorator declares the vehicle field as an input, which makes passing an actual value to it much easier.

Now let’s take a closer look at the template file for it:

div *ngIf="vehicle"
    h2{{vehicle.name}} properties/h2
    table
        tr
            tdlabelID: /label/td
            td{{vehicle.id}}/td
        /tr
        tr
            tdlabelName: /label/td
            tdinput [(ngModel)]="vehicle.name" placeholder="name" //td
        /tr
        tr
            tdlabelType: /label/td
            tdinput [(ngModel)]="vehicle.type" placeholder="type" //td
        /tr
        tr
            tdlabelMass: /label/td
            tdinput [(ngModel)]="vehicle.mass" placeholder="mass" //td
        /tr
    /table
/div
  • *ngIf=”vehicle”—Designates to only proceed with the content when the vehicle field has a value, which is needed to avoid errors when the selection is empty.
  • [(ngModel)]=”vehicle.name” (same for type and mass)—Implements bi-directional data binding between the input field and the corresponding property.

If an error with text like, “Can’t bind to ‘ngModel’ since it isn’t a known property of ‘input’” appears – then it means that the app modules weren’t properly configured. Go to src/app/app.module.ts and add FormsModule to the imports section. So, finally, app.module.ts should look like the following:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { VehicleListComponent } from './vehicle-list/vehicle-list.component';
import { VehicleDetailsComponent } from './vehicle-details/vehicle-details.component';

@NgModule({
  declarations: [
    AppComponent,
    VehicleListComponent,
    VehicleDetailsComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

No compilation errors should happen after this. A warning could remain, but it doesn’t break down any functionality.

Now, we need to change our VehicleListComponent to handle selection. Let’s add a selectedVehicle field and a method, onSelect, to handle selection.

Also, in the HTML template, we’ll need to add a tag for the details component. To make it work, we need to import VehicleDetailsComponent and add the corresponding directive. After making these changes, vehicle-list.component.ts will look like the following:

import { Component, OnInit } from '@angular/core';
import { VehicleService } from '../model/vehicle.service';
import { Vehicle } from '../model/vehicle';

@Component({
  selector: 'app-vehicle-list',
  templateUrl: 'vehicle-list.component.html',
  styleUrls: ['vehicle-list.component.css'],
  providers: [VehicleService]
})
export class VehicleListComponent implements OnInit {

  vehicles: Vehicle[];
  selectedVehicle: Vehicle;

  constructor(private vehicleService: VehicleService) {
    this.vehicles = this.vehicleService.getVehicles();
  }

  ngOnInit() {
  }

  onSelect(vehicle: Vehicle) { this.selectedVehicle = vehicle; }

}

Next, let’s change the vehicles list template, vehicle-list.component.html. We need to add the click handler to each table row to call the corresponding selection method—(click)=”onSelect(vehicle).“ Also, let’s add a tag for the vehicle details component below our table:

table class="tftable"
  trthID/ththName/ththType/ththMass/th
  tr *ngFor="let vehicle of vehicles"
      (click)="onSelect(vehicle)"
    td{{vehicle.id}}/td td{{vehicle.name}}/td td{{vehicle.type}}/td td{{vehicle.mass}}/td
  /tr
/table
vehicle-details [vehicle]="selectedVehicle"/vehicle-details

Your changes should be automatically picked up and compiled; please, look at Terminal+. If you haven’t closed your browser, you don’t need to do anything – the browser should be updated automatically. Switch to it and you’ll see:

vehicles-land-cruiser-80-properties
Perfect, it works! You can try editing any value under “properties,” and the change will be immediately reflected in the table — nothing extra needed for it.

A Little Bit of Styling

It looks pretty good now, but it’s a bit difficult to determine which row is selected. Let’s fix this. Add an attribute [class.selected]=”vehicle === selectedVehicle” to the tr tag in vehicle-list.component.html. Its meaning is pretty obvious—add a CSS class for the case when the current row’s vehicle equals the selected one. Of course, to make this work, we need to add the corresponding style to vehicle-list.component.css:

.selected { background-color: #CFD8DC !important;}

Let’s add a hovering style too! It’s as easy as adding one line to the CSS file:

table.tftable tr:hover {background-color:  left: .1em;}

vehicles-land-cruiser-80-properties-2
Great, our table looks much more interactive after this.

Inspecting

Possibly you’ve noticed that small vertical toolbar at the top right corner of the page in the browser? It’s a CodeLive toolbox, which can be very helpful for finding out what’s happening in your application and which components are being displayed. Let’s see how it works.

Click that wand icon – you’ll be able to see which component is under your cursor pointer. If you now click that grayed area – the component tree will be opened.

vehicles-trailer-1-properties
You can also see the component tree by clicking the list icon, which is above the wand icon in the CodeLive toolbox.

codelive-dashboard
In our case, a tree is pretty simple, but in the case of real applications, which could consist of a significant amount of components, such a tree with an ability to filter it could be very useful.
If you put your cursor near one of the items of this tree, you’ll see 3 actions allowing to open TS, HTML, and CSS files for a given component. It could be very useful for those who want to investigate an application created by some other person.

Debugging

Some people who are switching from desktop or mobile development to web development are complaining about the poor debugging tools offered for web developers – in the best case they need to debug in the browser, and in the worst case by using old tricks like printing values to the console or showing them in pop-ups. Don’t worry – Webclipse allows debugging in your favorite IDE.

Let’s put a breakpoint into the onSelect handler of our VehicleListComponent.

on-select-handler

Then go down to the Servers view and click on the “Debug application in Chrome” icon.

debug-application-in-chrome
Chrome will be re-launched. Click some entry in the Vehicles list to select it. The IDE will suggest that you switch to the Debug perspective. After this, you’ll see the stuff well-known to desktop or Android app developers – debug line marks, debug stack traces, and a variables view:

loaded-js-view
In the “Loaded JavaScript view” to the right of the source editor area, you can see JS files, which are loaded by the app.

Conclusion

As I said in the previous article, Typescript and Angular are great tools with which to start web development – they allow you to write code in on object-oriented style, without much headache with different browsers support, dynamic typing, etc.

Webclipse’s Angular tooling makes this even more convenient and friendly – you can create projects or components using modern GUI (without a direct use of the command line), inspect your component model using convenient and intuitive tooling, and debug your application inside the IDE in a way well-known to almost any programmer. On the other hand, you don’t lose the flexibility of the plain old command line – it’s still accessible for you in Terminal+ view, as well as an output of CLI commands called by wizards – IDE doesn’t try to hide any details from you.
In my opinion, the described set of tools is a very good choice for anyone who wants to start his or her experience in web development.

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*

cover letter