Loading...
3">Too many planets
` }) export class PlanetListComponent { planets: Planet[] = [ {"name": "Yavin IV", "diameter": 10200, population: 1000}, {"name": "Alderaan", "diameter": 12500, population: 2000000000}, {"name": "Hoth", "diameter": 80, population: 20000}, {"name": "Dagobah", "diameter": 8900, population: 3000}]; } *ngFor for displaying array Template Syntax *ngIf for conditional statementname = {{personName}}
` }) export class AppComponent { personName = 'kalle'; }bmi = {{mass / (height * height)}}
` }) export class AppComponent { } View handles the logic of calculating bmibmi = {{calculateBmi()}}
` }) export class AppComponent { mass : number = 0; height : number = 0; calculateBmi() : number { return this.mass / (this.height*this.height); } } Component handles the logic of calculating bmibmi = {{bmi}}
`, }) export class AppComponent { mass : number = 0; height : number = 0; bmi : number = 0; calculateBmi() : void { this.bmi = this.mass / (this.height*this.height); } } When clicking the button, call the method Method updates the bmiTesting lifecycle
` }) export class LifeCycleComponent implements OnInit, OnDestroy { ngOnInit() { console.log("init") } ngOnDestroy() { console.log("destroy") } } Interfaces are voluntary here, you do not need them{{user}}
' }) export class ChildComponent implements OnChanges { @Input() user = ''; ngOnChanges(): void { console.log('name changed'); } } Triggers event when input changes. user here is primitive type!{{user.name}}
' }) export class ChildComponent implements OnChanges { @Input() user = { name: '' }; ngOnChanges(): void { console.log('name changed'); } } This is not called! ngOnChanges won't detect changes inside of reference type!{{user.name}}
' }) export class ChildComponent implements DoCheck { @Input() user = { name: '' }; ngDoCheck(): void { console.log('name changed'); } } Detects also reference type updates...
• Structural directives: change the structure of the view • ngFor, ngIf ...January
February
Some other month
{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ state('on', style({ backgroundColor: 'yellow', transform: 'scale(1) rotate(360deg)' })), state('off', style({ backgroundColor: 'white', transform: 'scale(0.5) rotate(0deg)' })), transition('on => off', animate('500ms ease-in')), transition('off => on', animate('500ms ease-out')) ]) ] }) export class LightbulbComponent { private _state = 'on'; Define animation when state changes{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ state('on', style({ backgroundColor: 'yellow', transform: 'scale(1) rotate(360deg)' })), state('off', style({ backgroundColor: 'white', transform: 'scale(0.5) rotate(0deg)' })), transition('on => off', animate('500ms ease-in')), transition('off => on', animate('500ms ease-out')) ]) ] }) export class LightbulbComponent { private _state = 'on'; Display just "On" or "Off" inside of p{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ state('on', style({ backgroundColor: 'yellow', transform: 'scale(1) rotate(360deg)' })), state('off', style({ backgroundColor: 'white', transform: 'scale(0.5) rotate(0deg)' })), transition('on => off', animate('500ms ease-in')), transition('off => on', animate('500ms ease-out')) ]) ] }) export class LightbulbComponent { private _state = 'on'; Changes the state{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ state('on', style({ backgroundColor: 'yellow', transform: 'scale(1) rotate(360deg)' })), state('off', style({ backgroundColor: 'white', transform: 'scale(0.5) rotate(0deg)' })), transition('on => off', animate('500ms ease-in')), transition('off => on', animate('500ms ease-out')) ]) ] }) export class LightbulbComponent { private _state = 'on'; Trigger lightBulbState and use "On" or "Off"..{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ state('on', style({ backgroundColor: 'yellow', transform: 'scale(1) rotate(360deg)' })), state('off', style({ backgroundColor: 'white', transform: 'scale(0.5) rotate(0deg)' })), transition('on => off', animate('500ms ease-in')), transition('off => on', animate('500ms ease-out')) ]) ] }) export class LightbulbComponent { private _state = 'on'; The lightBulbState is defined here{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ state('on', style({ backgroundColor: 'yellow', transform: 'scale(1) rotate(360deg)' })), state('off', style({ backgroundColor: 'white', transform: 'scale(0.5) rotate(0deg)' })), transition('on => off', animate('500ms ease-in')), transition('off => on', animate('500ms ease-out')) ]) ] }) export class LightbulbComponent { private _state = 'on'; When state is on, use this style{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ state('on', style({ backgroundColor: 'yellow', transform: 'scale(1) rotate(360deg)' })), state('off', style({ backgroundColor: 'white', transform: 'scale(0.5) rotate(0deg)' })), transition('on => off', animate('500ms ease-in')), transition('off => on', animate('500ms ease-out')) ]) ] }) export class LightbulbComponent { private _state = 'on'; When state is off, use this style{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ state('on', style({ backgroundColor: 'yellow', transform: 'scale(1) rotate(360deg)' })), state('off', style({ backgroundColor: 'white', transform: 'scale(0.5) rotate(0deg)' })), transition('on => off', animate('500ms ease-in')), transition('off => on', animate('500ms ease-out')) ]) ] }) export class LightbulbComponent { private _state = 'on'; What kind of transitions to use when changing the state{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ state('on', style({ backgroundColor: 'yellow', transform: 'scale(1) rotate(360deg)' })), state('off', style({ backgroundColor: 'white', transform: 'scale(0.5) rotate(0deg)' })), transition('on <=> off', animate('500ms linear')) ]) ] }) If the same kind of animate, we can use <=> See http://easings.net/ for details about easy-in etc{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ state('on', style({ backgroundColor: 'yellow', transform: 'scale(1) rotate(360deg)' })), state('off', style({ backgroundColor: 'white', transform: 'scale(0.5) rotate(0deg)' })), transition('void => *', [...]), transition('* => void', [...]), ]) ] }) Instead of declaring the styles in states, now you declare them in the transition itself...{{state}}
', styles: ['p { display: inline-block; }'], animations: [ trigger('lightBulbState', [ transition(':enter', [...]), transition(':leave', [...]), ]) ] }) You can also use a cleaner syntax here :enter == void => * :leave == * => voidLightbulb!
`, styles: ['p { display: inline-block; }', 'a { display: block; }'], animations: [ trigger('lightBulbState', [ transition(':enter', [ style({transform: 'translateX(-200%)'}), animate(500) ]), transition(':leave', [ animate(500, style({opacity: 0, transform: 'translateX(500%)'})) ]) ]) ] }) export class LightbulbComponent { private _state = true; ... Will toggle the lightbulb off and on of the view state is now boolean because of the *ngIf When entering 1) set lightbulb off the screen 2)Animate it to original position When leaving, animate it to right and set opacity to 0 (invisible){{post.body}}
` }) export class ViewDetailComponent implements OnInit { post: Post = {id: undefined, title: '', body: '', userId: undefined}; constructor( private activatedRoute: ActivatedRoute, private http: HttpClient) {} ngOnInit() { // subscribe to "url" this.activatedRoute.params.subscribe((params: Params) => { // when changes, get id url value const id = params['id']; // Fetch content this.http.get('https://jsonplaceholder.typicode.com/posts/' + id).subscribe(jsonObject => { this.post = jsonObject; }); }); } }{{post.body}}
` }) export class ViewDetailComponent implements OnInit { post: Post = {id: undefined, title: '', body: '', userId: undefined}; constructor( private activatedRoute: ActivatedRoute, private http: HttpClient) {} ngOnInit() { // subscribe to "url" this.activatedRoute.params.subscribe((params: Params) => { // when changes, get id url value const id = params['id']; // Fetch content this.http.get('https://jsonplaceholder.typicode.com/posts/' + id).subscribe(jsonObject => { this.post = jsonObject; }); }); } } Getting the id value from url{{post.body}}
Back` }) export class ViewDetailComponent implements OnInit { post: Post = {id: undefined, title: '', body: '', userId: undefined}; constructor( private router: Router, private activatedRoute: ActivatedRoute, private http: HttpClient) {} back() { this.router.navigate(['view']); } ngOnInit() { // subscribe to "url" this.activatedRoute.params.subscribe((params: Params) => { // when changes, get id url value const id = params['id']; // Fetch content this.http.get('https://jsonplaceholder.typicode.com/posts/' + id).subscribe(jsonObject => { this.post = jsonObject; }); }); } } Navigating{{post.body}}
Back` }) export class ViewDetailComponent implements OnInit { post: Post = {id: undefined, title: '', body: '', userId: undefined}; constructor( private router: Router, private activatedRoute: ActivatedRoute, private http: HttpClient) {} back() { this.router.navigate(['view', {id: this.post.id}]); } ngOnInit() { // subscribe to "url" this.activatedRoute.params.subscribe((params: Params) => { // when changes, get id url value const id = params['id']; // Fetch content this.http.get('https://jsonplaceholder.typicode.com/posts/' + id).subscribe(jsonObject => { this.post = jsonObject; }); }); } } Giving the id back: http://localhost:4200/view;id=1Today is {{ todayDate | date:'dd.mm.yyyy'}} ` }) export class AppComponent { title : string = 'Planets' todayDate : Date = new Date() } Displays date in the following format
{{msg}}
` }) export class AddLocationComponent { latitude: number longitude: number msg: string = "" private url = "http://localhost:8080/api/locations/" constructor(private http: HttpClient) {} sendToServer() { let body = {"latitude": this.latitude, "longitude": this.longitude} this.http.post(this.url, body, {observe: 'response'} ).subscribe(response => { if(response.status === 201) { this.msg = `Saved with id = ${response.body.id}` } }) } } Expecting this data from backend Sending Json object to backend If we got 201 CREATED then display it in UIClick me
` }) export class AppComponent { doSomething(event: Event) { console.log(event); } } Base class for all the DOM Events Either MouseEvent or KeyboardEventClick me
` }) export class AppComponent { doSomething(event: Event) { console.log(event.target); } } Either or..
Click me
` }) export class AppComponent { doSomething(event: Event) { console.log(event.target.value); } } Angular will warn about this. The value is not present in event.targetClick me
` }) export class AppComponent { doSomething(event: Event) { const givenTarget: EventTarget = event.target; if (givenTarget instanceof HTMLInputElement) { const input: HTMLInputElement = givenTarget; console.log(input.value); } else if (givenTarget instanceof HTMLElement) { console.log(givenTarget.textContent); } } } Will output "Click Me" Will output given text Interface that HTMLInputElement and HTMLElement implemets{{debug}}
{{debug}}
{{debug}}
{{debug}}
{{debug}}
{{emailElement.className}}
{{debug}}
{{emailElement.className}}
{{debug}}
{{emailElement.className}}
{{debug}}
{{emailElement.className}}
{{debug}}
Form value: {{ personForm.value | json }}
` }) export class AppComponent { personForm = new FormGroup({name: new FormControl(), age: new FormControl()}); persons: Person[] = [{name: 'jack', age: 30}, {name: 'tina', age: 20}]; } Use .value to get the form data. The json pipe here transforms it to stringForm value: {{ personForm.value | json }}
` }) export class AppComponent { persons: Person[] = [{name: 'jack', age: 30}, {name: 'tina', age: 20}]; // personForm = new FormGroup({name: new FormControl(), age: new FormControl()}); personForm: FormGroup; constructor(private fb: FormBuilder) { this.personForm = fb.group({name: '', age: ''}); } } Use FormBuilder to quickly create the FormGroupForm value: {{ personForm.value | json }}
Form status: {{ personForm.status | json }}
` }) export class AppComponent { persons: Person[] = [{name: 'jack', age: 30}, {name: 'tina', age: 20}]; personForm: FormGroup; constructor(private fb: FormBuilder) { this.personForm = fb.group({name: ['', Validators.required], age: ''}); } } Pass an array of values. First the default value and then a validator Will output valid or invalid depending if name was given.name = {{personForm.get('name').value}}
name status = {{personForm.get('name').status}}
name pristine = {{personForm.get('name').pristine}}
name dirty = {{personForm.get('name').dirty}}
name untouched = {{personForm.get('name').untouched}}
name touched = {{personForm.get('name').touched}}
` })