Angular in 60 Min

¡Supera tus tareas y exámenes ahora con Quizwiz!

The file structure of an Angular Application. Package.json - like a manifest app with all of the dependencies. It also has scripts, and one of the commands is " ng serve " which is what we just did to start the application.

"build" will build-out all of the assets so we can upload to a server. dependencies show us what Angular is made up of a bunch of different packages.

ControlValueAccessor, what does it do?

- creates a bridge between Angular FormControl instances and native DOM elements.

FromArray , what does it do?

- tracks the same values and status for an array of form controls

How do you move up one directory ?

../ (dot dot /)

How do you import the interface if it is in the module file as Address?

../ (up on directory) /model/Address.js (down into model and grabbing the Address.js file. We do not have to put .js on the end of the file.

We have the app folder, which is our application. The app.mondule.ts ( a meeting place for our app) Everything needs to be imported into this file and placed in the modules file. Each thing goes into a different array.

1. Components will go into declarations. 2. Modules, like the forms modules will go into Imports 3. Services will go into providers.

When we want to insert the component we use what is in the selector, in this case my-app.

<body> <my-app>Loading AppComponent content here.....</my-app> </body>

Events and event binding. When the users interact with the application in the form of a keyboard movement, a mouse click, or a mouse over, it generates an event. The events are handled to perform an action. This is where event binding comes into the picture. In myApp.component.html what needs to be done to have a button call a myFunction() when the button is clicked?

<button (click)="myFunction($event)">Click Me </button> notice that we are passing the event $event to the function to print it out in the console.

How do we add a change event to it to call a function myChange?

<select (change)="myChange($event)"> <option *ngFor="let month of months">{{month}}</option> </select>

If we wanted to add an index, how would we do that?

<ul> <li *ngFor="let hobbies of hobby", let i = index> {{ i }} : {{ hobbies }} </li> </ul> // Gives us this: 0: Camping 1: Hiking 2: Cars

When Angular constructs a component tree the root module injector is already configured, so you can inject any global dependencies. Also, when angular instantiates a child component class, the injector for the parent component is also already set up so you can inject providers defined on the parent component including the parent component itself.

A component constructor is the is the only method that is called in the context of the injector so if you need any dependency that is the only place to get those dependencies. The @input communication mechanism is processed as part of following the change detection phase, so input bindings re not available in the constructor.

What allows us to loop through arrays:

A directive *ngFor="let hobby of hobbies" let is assigning a variable, and hobby is going to be equal to the iteration of of each value in hobbies. So, it will iterate through each element of hobbies. <li> {{hobby}} </li>

Reactive forms have methods to change a control's value pro-grammatically, which gives you the flexibility to update the value without user interaction.

A form control instance provides a setValue() method that updates the value of the form control and validates the structure of the value provided against the control's structure.

Angular is ?

A frontend / client side JavaScript framework. Used for SPA Created by Google Part of Mean Stack

Core features:

Components Data binding Directives Pipes Routing Typescript

Components are the basic building block of the UI An Angular application is a tree of Angular components.

Components are the basic building blocks of Angular. Components are sections of the user interface. You can have a: 1. Nav-bar component, 2. A blog post component 3. Sections of the page are components.

What must be the myApp.component.ts file in order to make the button work?

Down in the ngOnit there needs to be the function which the click event will call. myFunction(event){ alert("A click event has occured"); } If we pass the $event to the function and us console.log(event) we will see // mouse event

Just as the Form control instance gives you control over a single input field, a form group instance tracks the form state of a group of form control instances (for example a form).

Each control in a form group instance is tracked by name when creating the from group. The following example shows how to manage multiple form control instances in a single group.

Every application has a core app compoents and every component we create is nested inside the app component.

First we import the component package from the angular core library. import { Component } from ' @angular/core ';

Creating a Nested Group We may want to break a large form into smaller more manageable forms. An address is a good example of info that can be grouped together.

Form groups can accept both form control, and form group instance as children. This makes composing complex forms easier and you can logically group together the like data.

What do both Ractive and Template driven forms share in common? What building blocks do they share in common?

FormControl - tracks value and validation status of an individual form control. FormGroup - tracks the same values and status for a collection of form controls. FromArray - tracks the same values and status for an array of form controls. ControlValueAccessor- creates a bridge between Angular FormControl instances and native DOM elements.

Model To View steps Reactive-Forms 1. The user calls the favoriteColorControl.setValue() method, which updates the FormControl value. 2. The FormControl instance emits the new value through the valueChanges observable. 3. Any subscribers to the valueChanges observable receive the new value. 4. The control value accessor on the form input element updates the element with the new value.

FormControl instance value is set and valuChanges event fires.

Address could be a huge object, and you really do not want all of that up in the ngOninit(), there is a better way of doing this. You can use an interface that will map out the model of the class. You can put the interface in its own file, and import it / and use it from the interface file.

Go down at the bottom, outside of everything else and do an interface for address.

If we look at app.module.ts we find our component is added for us as an import. import { UserComponent } from './components/user/user.component'; You also find it in the declarations: @NgModule({ declarations: [ AppComponent, UserComponent ], if you manually created the folder you would have to add all the by your self.

If we look at user.component.ts we get: import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-user', templateUrl: './user.component.html', styleUrls: ['./user.component.css'] }) export class UserComponent implements OnInit { constructor() { } ngOnInit() { } }

You can see that it added ngOnInit ( ) - this is a lifecycle hook and well run when the component is initialized, so most of the things you can do in the constructor you can also do here. It is recommended in most cases.

If we look in the user.component.html all we see is user works. we do not see this in the browser because we have not added the component to the main app. so, we can look at the @Component, and the selector : 'app-user' this is the name of our component, and what we use to insert it into other components. as <app-user> </app-user>

Reactive-Driven forms are more robust, more scalable, reusable, and testable. Template-driven forms are useful for adding a simple form to an app, such as an email list or sign-up form, but they do not scale well. What is the rule of thumb when deciding which forms to use?

If you have a very basic form requirement and logic that can be managed solely in the template, use template-driven forms. Template forms "simplicity over the structure "

Notice that in the app.component.ts file we have Import { Component } from '@angular/core' @Component ( { selector: 'app-root', templateUrl: ' . /app.component.html ' styleUrls : [' /app.component.css] }) export class AppComponent { title = 'app'; }

In export we are setting a dynamic variable title = 'app' and if you look in the html we are outputting : <h1> Welcome to {{ title }} </h1>

Reactive Forms: Reactive forms provide a model-driven approach to handling form inputs whose values change over time.

In object-oriented and functional programming, an immutable object (unchangeable object) is an object whose state cannot be modified after it is created. This is in contrast to a mutable object (changeable object), which can be modified after it is created.

The strict checks of the setValue() method help catch nesting errors in complex forms, while patchValue() fails silently on those errors.

In the ProfileEditorComponent, use the updateProfile method to update the first name and street address for the user.

See the nesting of Address:

It is easy, just add another FormGroup({ objects }) to your parent group. export class ProfileEditorComponent { profileForm = new FormGroup({ firstName: new FormControl(''), lastName: new FormControl(''), address: new FormGroup({ street: new FormControl(''), city: new FormControl(''), state: new FormControl(''), zip: new FormControl('') }) }); }

In our HTML we use the <form tag> <form [FormGroup]='myFormGroup' > <input type='text' formContorlName='firstname'> <input type='text' fromControlName='lastName'>

Just as the form group contains a group of controls, the myFormGroup FormGroup is bound to the form element with the FormGroup directive, creating a communication layer between the model and the form containing the inputs.

Even if you set the name : siring = "Sam the man" this gets initialized in the constructor, but the ngOnInit() comes in and overrides it. If you comment the ngOnInit() out, then you would get the "Sam is the man"

Just to be clear: export class UserComponent implements OnInit() { name:string= "Steve Smith"; age : number; email : string address{ street:string, city:string, state:string } constructor() {} runs ngOnInit() {} runs over-writing the Steve Smith

So, we need to insert our app-user in the main app.component.html file and an insert is: <app-user> </app-user> So if we go into our app-user html component and put <h1>Hello World</h1> It will now show up on the browser page, because it is in our main app.component.html

Lets add a property in our export class UserComponent implements OnInit { name = ' John Doe '; constructor() { } } Now we can take this property into our template and use string interpolation { {String interpolation } } to input it into our html and output it somewhere. user.component.html <h2> hello {{name}} </h2>

constructor () and ngOninit() both run when the component is run. Constructor ( ) ran then the ngOninit ( ) ran - so what you will usually see is these properties will have a type associated with them. So we will change this name to a string name:string = ' John Doe '; So, you do not have to set the property, you would normally do this in the ngOnInit( )

Lets add a property in our export class UserComponent implements OnInit { name:string; constructor() { console.log('Constructor Ran'); } ngOninit() { this.name='John Doe' }

Template-Driven forms are inferior. Thus unless you are doing something very simple, and need no structure, use template-driven forms. If you are working on a large scale project that must be scalable and manageable, use Reactive-Driven forms.

Look up template driven forms.

<label> Name: <input type = "text" [formControl]="name"> </label> Using the template binding syntax, the form control is now registered to the name input element in the template. The form control and DOM element communicate with each other; the view reflects changes in the model, and the model reflects changes in the view.

Note: For a more detailed list of classes and directives provided by ReactiveFormsModule, see the Reactive forms API section.

So, lets set come other names in the export class: name:string; age: number; Then we can go to our ngOninit ( ){ this.name : this.age : 39; email : string, this.address = { street:'50 Main Street', city:'Atlanta', state:'Ga' } }

Now, if you go in and change the state to a zip: state:30011, then you will get an error, because Angular is looking at the contents under the export class as a model.

Keep in mind that to introduce the Form: <form [formGroup]='profileForm'(ngSubmit)='onSubmit()'> To introduce the new address formgroup nested within profileForm we do not use the [ formGroup ], we use formGroupName="address" <div formGroupName="address">

Parent for the overall form gets the [ ] and child does not. Also, we used a <div> to separate the child group from the parent group, nesting it within the HTML.

Why Angular

Rapid Development & code generation Code organized into encapsulated components. Dynamic Content Cross platform

Managing Control Values: Reactive forms give you access to the form control state. You can manipulate the current state and value through the component class or the component template. {{name.value}} in the html file will display the value as you type in the input box.

Reactive forms provide access to information about a given control through properties and methods provided with each instance. Read about FormControl properties and methods in the reactive forms API Section.

In Angular, there are two different approaches to forms. They both capture events from the view, validate user input, and both track changes. But the process form data differently. What are the two approaches?

Reactive-Driven AND Template-Drive Forms

In template-driven forms, the source of truth is the template.

Simplicity over structure: Can only access FormControl instance via NgModel directive

Use the constructor of FormControl to set its initial value. which in this case is an empty string. export class NameEditorComponent { name = new FormControl(''); } By creating this class, you get immediate access to listen for, update, and validate the state of the form input.

Step 3 Registering the Control in the template After creating the control you must register it with the template. Update the template with the form control using the formControl binding provided by FormControlDirective including a ReactiveFormsModule.

When Angular starts change detection the component tree is constructed and the constructors for all components in the tree have been called. Also, at this point every component's template nodes are added to the DOM.

Stepping through the process: Angular starts bootstrapping the app. Angular creates classes for each component calling MyAppComp constructor. Angular resolved all dependencies that are injected into MyAppComp and provides them as parameters. Angular creates the DOM node, which is the host element of the my-app component. Then it creates the host element for the child-comp and calling ChildComponent constructor. Only then Angular runs change detection and updates bindings for the my-app and calls ngOnInit on the MyAppComp. instance. Then it proceeds to update the bindings for the child-comp and calls ngOnInit on the child comp. class.

What is Typescript?

Superset of JavaScript with added features -Created by Microsoft -Class-Based object-oriented programming. -Standard ES5 does not offer this, angular components are classes themselves.

Forms. There are two types of forms in Angular 4. What are they?

Template Drive Forms Most of the work is done in the template. Model Drive Forms Most of the work is done in the component class.

To create an instance you use the "New" Operator. const = componentInstance = new Mycomponent() So, if you omit the constructor class, it is transpiled into an empty funtion: class MyComponent() { }

The difference related to the component initialization process. This is huge between the two form a perspective of the component initialization process. Angular bootstrap process consists of the two major stages: constructing components tree running change detection The constructor is called when angular constructs the components tree. All lifecycle hooks including ngOnInit are called as part of the change detection phase.

In the component.ts we create a new FormGroup, naming the group object. I say object because look inside the FormGroup( { } ) myFormGroup = new FormGroup( { firstName:FromControl( ' ' ) lastName:FormControl( ' ' ) } ); The individual forms are now collected within the group.

The form group tracks the status and changes for each of its controls, so if one of the controls changes, the parent control also emits a status or value change. As you define the model, you must update the template to reflect the model in the view.

import { Component } from '@angular/core'; import { FormControl } from '@angular/forms'; @Component({ selector: 'app-reactive-favorite-color', template: ` Favorite Color: <input type="text" [formControl]="favoriteColorControl"> ` }) export class FavoriteColorComponent { favoriteColorControl = new FormControl(''); }

The source of truth provides the value and status of the form element at a given point and time. In reactive forms, the forms model is the source of truth. The form model is the FormControl instance.

onSubmit( ) { console.log(this.profileForm.value) } comp.HTML <button type - "submit" [disable]="!profileFormValid">Submit</button> Notice the form validation. We are not doing it now, but if we were the button would not enable unless the validation is good.

The submit event is emitted by the form tag using the native DOM event. You trigger the event by clicking a button with submit type.

We want to generate a component in a components folder called user. This is done automatically for us by typing: ng g component components/user

The system will then generate: user . component . ts file is typescript file, user . componentspec . ts is testing user . component . css is the css file user . component . html file is the html template

Getting back to our Angular in 60 min: It is better with larger objects to place the address in a class or a interface that maps out the address. So, below everything, we can create an interface, or even better place the file in a models folder and import the model's folder to our component.

Then import {Address} from '../../models/models.js'; and use as Address.street and so on.

Decorators allow us to mark a class as an Angular component & provide metadata that determines how the component should be processed, instantiated and used at run-time. The selector is custom tag we are going to use to insert our component.c

Then a decorator is made: @Component({ selector : 'my-app', template : 'path to template' })

With reactive forms, the form model is explicitly defined in the component class. The reactive form directive (in this case FormControlDirective) then links the existing FormControl instance to a specific form element in the view using a value assessor (ControlValueAccessor Instance)

There is a direct access to FormControl instance after link is created by FormControlDirective

You have also Angular-cli.json what does this have to do with?

This has to do with output directories when you build your project, and a lot of configurations. If you want to load syle sheets, and other things.

Creating a FormGroup instance import { FormGroup, FormControl } from '@angular/forms';

This imports the necessary items into the component: FormGroup, and FormControl.

Even though the address element in the form group is a child of the overall provileForm element in the group, the same rules apply with value and status changes. Changes in the status and value from the nested form group propagate to the parent from the group, maintaining consistency with the overall model.

To add the address to the html, we create a new <div formGroupName="address"> //inputs go here for the street, city, state..ect. </div>

For example, when retrieving form data from a backend API or serve, use the setValue() method to update the control to its new value, replacing the old value entirely.

To update a value we can go to the component.ts file. updateName() { this.name.setValue('Nancy') } Then we create a click event <button (click)="updateName( )"><Click to Update</button> The model is the source of truth for the control, so you click the button, the value of the input is changed within the component class, overriding the its current value.

What does FormControl do?

Tracks value and validation status of an individual form control.

Data Flow - RDF and TDF follow two different strategies when handling form input. In reactive forms, each form element in the view is directly linked to a form model (FormControl Instance). Updates from the view to the model and from the model to the view are synchronous and are NOT dependent on the UI rendered.

View too Model FormControl instance value is set and valueChanges event fires. favoriteColorControl.setValue("blue")

Generating Form Controls - The formBuilder service has three methods: control ( ) group ( ) array ( ) Factory Methods for generating instances in the component classes including form controls, form groups, and form arrays.

We can use the group method to create the profileForm controls.

We have an array of months called months = ["January", "Feburary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; We want them in a drop down; how do we loop through them in the view?

We use the drop down html code: <select> <option></option> </select> <select> <option *ngFor="let month of months">{{month}}</option> </select>

Use of patchValue(): <button (click)="updateProfile( )">Update</button> updateProfile( ){ this.profileForm.patchValue({ firstName:'Jeff', address:{ street:'123 Drew Street' } }); }

When the user clicks the Update button, the updateProfile() fires and uses patchValue() method to update the new values . Notice that street is provided in an object inside the address property. This is necessary because the patchValue() method applies the update against the model structure. PatchValue() method only updates properties that the from model define.

The template-driven form directive NgModel is responsible for creating and managing the FormControl instance for a given form element. It is less explicit but you no longer have direct control over the form model.

Why not to use template-driven forms. There is no structure "simplicity over structure". This effects reliability, it becomes harder to understand the forms structure because there is no structure. Validators- if we want to use TDF we must create custom directive in addition to the validation functionality.

How do you show the array hobbies in the html?

You can do {{hobbies}} // and get a comma separated list of the hobbies, or you can iterate through the list.

bootstrap [AppComponent] because this is the main app. So, just remember that when you create anything you need to bring it into this file.

app.component.ts file is typescript file, app.componentspec.ts is testing app.component.css is the css file app.component.html file is the html template

Saving Data: In a real scenario you want to capture the form value and make it available for further processing outside the component. The FormGroup directive listens for hte submit event emitted by the form element and emits an ngSubmit event that you can bind to a callback function.

comp.HTML <form [formGroup]='profileForm' (ngSubmit) = ' onSubmit ( ) ' The onSubmit( ) method in the ProfileEditor component captures the current value of profileForm. Use the EventEmitter to keep the form encapsulated and to provide the form value outside the component.

Data binding is the string interpolation. We declare a value to a variable and then we bind the data to the html components using string interpolation. {{variable}}

data from the component ts file is bound to the component html file with string interpolation. {{value}}

Where do all components go that you add to the program

declarations under @NgModule @NgModule({ declarations: [ AppComponent, UserComponent ],

Then we have the component class.

export class AppComponent { name = ' Angular '; } In this class it is called AppComponent, and we are defining a variable "name" a dynamic variable which can be used in the template by using {{ name }} or what we call string interpolation.

This is what was mentioned before, a with reactive forms, the form model is explicitly defined in the component class.

export class NameEditorComponent { name = new FormControl(''); }

How do you export the interface from the .ts file?

export interface Address{ street:string, city:string, state:string, zip:number }

Where do you set a hobbies array? What is the syntax?

hobbies:string[ ] if a string array hobbies:any[ ] if anything array hobbies:number[ ] if number array

What is the difference between ngOnInit() and the Constructor in its uses? ngOnInit() is just a method on a class which structurally is not different to any other method on a class. They could have named it anything, but they named it ngOnInit(). During compilation Angular compiler checks whether a component has this method implemented and marks the class with the appropriate flag. export const enum NodeFlags { OnInit = 1 << 16 } This flag is then used to decide whether to call the method on a component class instance or not during change detection.

if (def.flags & NodeFlags.Oninit && ){ componentClassInstance.ngOnInit(); } The constructor, in turn, is a different thing. Regardless if you implement it or not, in Typescript class it still will be called when creating an instance of a class. This is because a typescript class constructor is transpired into a JavaScript constructor function. class MyComponent { constructor () { console.log('Hello'); } } Transpiled into: function MyComponent() ( console.log('Hello') )

Template-Driven Forms: Here is the same component with an input field for a single control implemented using template-driven forms.

import { Component } from '@angular/core'; @Component({ selector: 'app-template-favorite-color', template: ` Favorite Color: <input type="text" [(ngModel)]="favoriteColor"> ` }) export class FavoriteColorComponent { favoriteColor = ''; }

With Reactive forms, the form model is explicitly defined in the component class.

import { Component } from '@angular/core'; import { FormControl } from '@angular/forms'; @Component({ selector: 'app-reactive-favorite-color', template: ` Favorite Color: <input type="text" [formControl]="favoriteColorControl"> ` }) export class FavoriteColorComponent { favoriteColorControl = new FormControl(''); }

Generating form controls with FormBuilder Service. Creating form control instances manually can become repetitive when dealing with multiple forms. The FormBuilder Service provides convenient methods for generating controls. From where do we import the FormBuilder class?

import { FormBuilder } from '@angular/forms'; FormBuilder is a service, thus we inject he dependencies into the constructor of the component. constructor(private fb: FormBuilder) { }

Services allow us to do something that is repeated only one time, and then we can inject it into other components throughout the program. All services have this injectable package we get from the Angular core. This allows us to inject it as a dependency into a component.

import { Injectable } from '@angular/core'; import { User } from ' ./user '; **Inerface import { USERS } from './mock-users'; ** Data @Injectable( ) ** Decorator export class UserService { export Users( ): User[ ] { getUsers( ) return USERS; } } then you have the class itself.

Step 1: Registering the reactive forms module. src/app/app.module.ts Import the ReactiveFormsModule into the app.module file. With all imports of this kind, we must add it to the imports array: Declarations - our components we add. Imports - from the angular modules Providers - services

import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ imports: [ // other imports ... ReactiveFormsModule ], }) export class AppModule { }

Step 2: The FormControl class is the basic building block when using reactive forms. Import this to your component and then create a new instance of for form control to save as a class property.

import {FormsControl} from '@angular/forms' export class NameEditorComponent { name = new FormControl(''); }

Start with the Template Driven Form. What must be imported to the app.component.ts file before we can start ?

import {FormsModule} from ' @angular/forms '

Where else does FormsModule need go to property work?

imports: [ BrowserModule, HttpModule, FormsModule ]

How do you create an interface named with an object address?

interface Address { street:string, city:string, state:string, zip:number }

We also have Services in Angular. Classes that send data and functionality across components. This keeps components:

lean DRY - Don't repeat yourself Ideal place for Ajax Calls

On the button click event, add a method to add an item to the month array when clicked. Add MyMonth to the array months.

myFunction(event) { this.months.push("MyMonth"); alert("A click event has occurred"); }

Then to create a angular application you type what?

ng new nameOfApp (myApp) This generates a new Angular app. Now you simply want to CD into the new folder, and we then should be able to run the app on a development server.

Constructor - mostly used to for Dependency Injection DI . However, the usage of a constructor is not limited to DI. For example, router-outlet directives of @angular/router module uses it to register itself and its location (viewContainerRef) with the router ecosystem. Common practice is to put as little logic into the constructor as possible.

ngOnInit - Angular calls ngOnInit when it has finished creating a component DOM, injected all requited dependencies through the constructor and processed input bindings. So, this makes a good place to have all required information available which makes it a good place to perform initialization logic. It is common to use ngOnInit to preform initialization logic even it this logic does not depend on DI, DOM or input bindings.

The best way to install Angular is through the CLI. This uses the NPM node package manager.

npm install -g @angular/cli

What are some common events in JavaScript ?

onclick onchange onload onmouseover onkeydown onmouseout All of these are mouse events except the onload event. If you pass $event to the function and then consol.log(event) you will get mouse event.

Remember that the Reactive Forms create an instance of the FormControl() with the export class of the component. This gives us direct control over the FormControl, and you get direct instant access to listen for, update and validate the state of the form input. When using group, we group the FormControls within the group object. property: value

profileForm = new FormGroup({ firstName:new FormControl(' '); lastName:new FormControl(' '); });

When updating a group instance that contains multiple controls, you may want to update parts of the model. We can update specific parts of a form control data model. Patching the Model Value: There are two ways to update the model value:

setValue() methods to set a new value for an individual control. The setValue() method strictly adheres to the structure of the form group and replaces the entire value for the control. patchValue() method to replace any properties defined in the object that have changed in the form model

How do you initialize the address?

this.address={ street:'50 Main Street', city:'Atlanta', state:'Ga', zip:77886 }

What does FormGroup do?

tracks the same values and status for a collection of form controls.

How would you get the index to start at one?

{{ i + 1 }} or you could do 2 if you wanted it to start at 2.


Conjuntos de estudio relacionados

Introduction to Analysis of Algorithms

View Set

12 Basic Functions - Domain and Range

View Set

Skeletal System - Shapes of Bones

View Set

Organizational Behavior SB Ch 4, 5, 6

View Set

Med/Surg-Chapters 7, 33, and 61 Exam

View Set