More Related Content Similar to Angular for Java Enterprise Developers: Oracle Code One 2018 (20) Angular for Java Enterprise Developers: Oracle Code One 201816. Java 10: var
!// No!!!
var userName;
userName = user.getName();
!// Yes!
var userName = user.getName();
19. Optional: adding return types
function orderByName(a: User[]): User[] {
let result = a.slice(0);
result.sort((x, y) !=>
x.name.localeCompare(y.name));
return result;
}
But someCmes it might help finding bugs in the code
21. Interfaces: two concepts (2/2)
interface Person {
name: string;
age: number;
}
interface Contact extends Person {
phone: string;
}
Or it can be used in the OO concept
25. Defining Types on the go + Unions
type Shape =
| { type: 'circle'; radius: number }
| { type: 'square'; w: number }
| { type: 'rectangle'; w: number, h: number };
26. Defining Types on the go + unions
function calculateArea(shape: Shape) {
switch (shape.type) {
case 'circle': return Math.PI * shape.radius !** 2;
case 'rectangle': return shape.w * shape.h;
case 'square': return shape.w !** 2;
}
throw new Error('Invalid Shape');
}
const myCircle: Shape = { type: 'circle', radius: 2 };
calculateArea(myCircle);
27. Enums
enum UserActionTypes {
LOAD_REQUEST = '[User] Load Request',
LOAD_SUCCESS = '[User] Load Success'
}
type UsuarioActions =
| { type: UserActionTypes.LOAD_REQUEST }
| {
type: UserActionTypes.LOAD_SUCCESS;
payload: User[];
};
28. Getters and Setters: Don’t
export class Contact {
private _name: string;
get name() {
return this._name;
}
set name(name: string) {
this._name = name;
}
}
29. Getters and Setters: Do
export class AuthService {
private loggedIn = new BehaviorSubject(false);
get isLoggedIn() {
return this.loggedIn.asObservable();
}
}
isLoggedIn = AuthService.isLoggedIn;
33. > npm install -g @angular/cli
> ng new my-project
> cd my-project
> ng serve || npm run start
41. import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { ModalModule } from 'ngx-bootstrap/modal';
import { ContactDetailsComponent } from './components/contact-details/contact-details.component';
import { ContactFormComponent } from './components/contact-form/contact-form.component';
import { ContactListComponent } from './components/contact-list/contact-list.component';
import { ContactsContainerComponent } from './contacts-container/contacts-container.component';
import { ContactsRoutingModule } from './contacts-routing.module';
@NgModule({
imports: [
CommonModule,
ReactiveFormsModule,
ContactsRoutingModule,
ModalModule.forRoot()
],
declarations: [
ContactsContainerComponent,
ContactListComponent,
ContactFormComponent,
ContactDetailsComponent
],
entryComponents: [ContactDetailsComponent]
})
export class ContactsModule {}
Import classes
42. import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { ModalModule } from 'ngx-bootstrap/modal';
import { ContactDetailsComponent } from './components/contact-details/contact-details.component';
import { ContactFormComponent } from './components/contact-form/contact-form.component';
import { ContactListComponent } from './components/contact-list/contact-list.component';
import { ContactsContainerComponent } from './contacts-container/contacts-container.component';
import { ContactsRoutingModule } from './contacts-routing.module';
@NgModule({
imports: [
CommonModule,
ReactiveFormsModule,
ContactsRoutingModule,
ModalModule.forRoot()
],
declarations: [
ContactsContainerComponent,
ContactListComponent,
ContactFormComponent,
ContactDetailsComponent
]
})
export class ContactsModule {}
Import other modules
Import
components used in this
module
46. Lazy Loading Strategies
const routes: Routes = [
{
path: 'module-2',
loadChildren: './module-2/module-2.module#Module2Module',
data: { preload: true } !// pre-load - background
},
{
path: 'module-3',
loadChildren: './feature-3/module-3.module#Module3Module'
}
];
@NgModule({
imports: [
RouterModule.forRoot(routes, {
preloadingStrategy: AppCustomPreloader
})
], !// our custom logic
})
export class AppRoutingModule {}
47. Lazy Loading Strategies
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';
export class AppCustomPreloader implements PreloadingStrategy {
preload(route: Route, load: Function): Observable<any> {
return route.data !&& route.data.preload ? load() : of(null);
}
}
51. Create Wrappers
@Injectable()
export class ApiService {
constructor(public http: HttpClient) { }
getRequest<T>(url: string, params!?: any) {
return this.http.get<ServerResponse<T!>>(url, {
params: this.getQueryParams(params)
})
.take(1); !// as simple Ajax call, we only need 1 value
}
postRequest(url: string, body: any) {
!// POST
}
private getQueryParams(params: any) {
!// logic to create the query params for http call
}
downloadFile(url: string, params!?: any) {
!// logic for file download
}
}
52. Keep consistency
@Injectable()
export class TasksService {
constructor(public http: ApiService) { }
getAllTasksWithPaging(start = 0, limit = 100) {
return this.http
.getRequest<Task[]>(API.READ_TASKS, {start: start, limit: limit});
}
getById(id: number) {
return this.http.getRequest<Task>(`${API.READ_TASKS}/${id}`);
}
}
54. Inheritance
export abstract class BaseFormComponent implements IFormCanDeactivate {
protected formSubmitAttempt: boolean;
protected validateDirty = true;
form: FormGroup;
constructor() {
this.formSubmitAttempt = false;
}
isFieldInvalid(field: string) {
!// some logic here
}
onSubmit() {
this.formSubmitAttempt = true;
!// generic logic for all forms
}
canDeactivate(): Observable<boolean> {
return this.modalService.showConfirm(
'DoYouWantToLeavePage',
'DoYouWantToLeavePageMsg'
);
}
onCancel() {
this.location.back();
}
}
55. Generic “Dao” Service
@Injectable()
export class CRUDService<T> {
constructor(public http: HttpClient, private API_URL) {}
load() {
return this.http.get<T[]>(this.API_URL);
}
create(record: T) {
return this.http.post<Task>(this.API_URL, record);
}
update(record: T) {
return this.http.put<Task>(`${this.API_URL}/${record.id}`, record);
}
remove(id: string) {
return this.http.delete<T>(`${this.API_URL}/${id}`);
}
}
62. Multiple Angular Environments
!// environment.dev.ts
export const environment = {
production: false,
baseUrl: '/'
};
!// environment.ts
export const environment = {
production: false,
baseUrl: '/api/'
};
!// environment.prod.ts
export const environment = {
production: true,
baseUrl: '!../'
};
64. Back-end endpoints
import { environment } from '@env/environment';
export class API {
static readonly BASE_URL = environment.baseUrl;
static readonly CLIENTS = `${API.BASE_URL}clients`;
}
!// this.http.get(API.CLIENTS)
65. Integration with Back-end: No CORs
proxy.conf.json
{
"/api": {
"target": "http:!//localhost:8080",
"secure": false
},
"logLevel": "debug"
}
const PROXY_CONFIG = [
{
context: ['/api'],
target: 'http:!//localhost:8080',
secure: false,
logLevel: 'debug',
pathRewrite: { '^/api': '' }
}
];
module.exports = PROXY_CONFIG;
proxy.conf.js
72. Maven Front-end Plugin
!!!<!-- Angular build !!-->
<plugin>
<groupId>com.github.eirslett!</groupId>
<artifactId>frontend-maven-plugin!</artifactId>
<version>1.6!</version>
<configuration>
<nodeVersion>v10.0.0!</nodeVersion>
<npmVersion>6.4.1!</npmVersion>
<workingDirectory>./!../angular-rest-crud!</workingDirectory>
<installDirectory>${user.home}/.node!</installDirectory>
!</configuration>
<executions>
!!!<!-- Steps for Angular prod build !!-->
!</executions>
!</plugin>
73. Maven Front-end Plugin
<execution>
<id>install node and npm!</id>
<goals>
<goal>install-node-and-npm!</goal>
!</goals>
<configuration>
<nodeVersion>v10.0.0!</nodeVersion>
<npmVersion>6.4.1!</npmVersion>
!</configuration>
!</execution>
<execution>
<id>npm install!</id>
<goals>
<goal>npm!</goal>
!</goals>
<configuration>
<arguments>install !</arguments>
!</configuration>
!</execution>
78. Docker: Java / Spring
FROM maven:3.5.4-jdk-10-slim
WORKDIR /usr/src/java-code
COPY . /usr/src/java-code/
RUN mvn package
WORKDIR /usr/src/java-app
RUN cp /usr/src/java-code/target!/*.jar ./app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
79. Docker: Angular
##### Angular build
FROM node:latest as angular-client
WORKDIR /app
COPY package.json package.json
RUN npm install
COPY . .
RUN npm run build !--prod
##### Nginx
FROM nginx:alpine
VOLUME /var/cache/nginx
COPY !--from=angular-client /app/dist/angular-rest-crud /usr/share/nginx/html
COPY ./config/nginx.conf /etc/nginx/conf.d/default.conf
80. Docker: Angular + NGINX + proxy
# proxy
location /api {
proxy_pass http:!//129.150.111.200:8083;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_buffering off;
proxy_set_header Accept-Encoding "";
}