> Samples
> Angular Samples
All Samples: click here to view all zip files
Check the updates section If following the samples using Angular 8
Samples on this page - Scroll Down
Here is a full project, setup from start to end with Firebase authentication.
> Angular Samples
All Samples: click here to view all zip files
Check the updates section If following the samples using Angular 8
Samples on this page - Scroll Down
- Sample 1: Property & Event Binding and View Encapsulation - Angular 6
- Sample 2: Working with Directives
- Sample 3: Using Services
- Sample 4: Routing
- Sample 5: Simple Observable with RxJs Compat
- Sample 6: Simple Observable Subject with RxJs Compat
- Sample 7: Simple Observable without RxJs Compat
- Sample 8: Forms: Template Driven
- Sample 9: Forms: Reactive
- Sample 10: Using Pipes
- Sample 11: Getting the Parameters from URL
- Sample 12: Using HTTP
- Sample 13: Setting up Authentication
- Sample 14: Modules Optimization to learn consolidating modules and creating and sharing modules.
Here is a full project, setup from start to end with Firebase authentication.
Sample #1
Property & Event Binding and View Encapsulation - Angular 6
This sample covers property and event binding with view encapsulation. Tasks completed in this sample.
- Created three new components: GameControl, Odd and Even
- Created with > ng g c XXXX --spec false
- The GameControl Component have buttons to start and stop the game
- When starting the game, an event (holding a incrementing number) gets emitted each second (ref = setInterval())
- The event is listenable from outside the component
- When stopping the game, no more events are emitted (clearInterval(ref))
- A new Odd component gets created for every odd number emitted, the same happens for even Component (on even numbers)
- Simply output Odd - NUMBER or Even - NUMBER in the two components
- Styled the element (e.g. paragraph) holding output text differently in both components
Download Project (zip): SampleDataEventBinding
Sample #2
Working with Directives
This sample covers use of- Structural Directives (*ngIf and *ngFor)
- Attribute Directives (ngClass and ngStyle)
- Building and Using Custom Attributes
- A simple example
- Using Renderer
- Using HostListener to listen to HostEvents
- Using HostBinding to Bind to Host Properties
- Binding to Directive Properties
- Building and using a custom Structural Directive
- Use of ngSwitch
Download Project (zip): SampleDirectives
Sample #3
Using Services
- Services are in app/shared/services folder.
- Moving the users between active and inactive arrays. Array is in UsersService.
- The app has UsersService which manages the active and inactive users.
- UsersService uses the CounterService via @Injectable()
- CounterService counts the number of active->inactive and inactive->active actions.
- CounterService and UsersService added to the providers array in app.modules.ts
- app-active-users and app-inactive-users are referenced inside the app.component.html
Environment: MS VS Code, bootstrap 3 and Angular 6
Download Project (zip): SampleServices
Important
If you're using Angular 6+ (check your package.json to find out), you can provide application-wide services in a different way.Instead of adding a service class to the providers[] array in AppModule , you can set the following config in @Injectable() :
@Injectable({providedIn: 'root'})
export class MyService { ... }
This is exactly the same as:
export class MyService { ... }
and
import { MyService } from './path/to/my.service';
@NgModule({
...
providers: [MyService]
})
export class MyService { ... }
Using this new syntax is completely optional, the traditional syntax (using providers[] ) will still work. The "new syntax" does offer one advantage though: Services can be loaded lazily by Angular (behind the scenes) and redundant code can be removed automatically. This can lead to a better performance and loading speed
Sample #4
Routing
- In the app, we got three sections:
- Home
- Servers
- View and Edit Servers
- A Service is used to load and update Servers
- Users
- View User
- The app will be improved by adding routing.
- We need to define all the routes and place them in app.routing.module and then used it in app.module.
- in the app.component.html
directive is placed to mark the place where selected route template will be displayed - Tab navigation is provided with [routerLink]
- Active tab is marked with [routerLinkActive]. Please note [routerLinkActiveOptions]="{exact: true}" on Home tab since this gets active class when we click Users or Servers as well.
- Loading the route programatically. For this
- Inject the instance through constructor as private router: Router
- and then navigate to it this.router.navigate(['/servers']);
- check home component and html for more details
- Passing parameters to routes
- specify a route in app.modules as { path: 'users/:id', component: UserComponent }, we'll be passing the id dynamically to get the user
- To get the id, in the component constructor inject ActivatedRoute and then use var id: number = this.activatedRoute.snapshot.params['id']
- Now when we refresh the same component with a different id and name, the url will show the new id and name but the content will not refresh. In this case we'll need to subscribe to the change as
this.activatedRoute.params.subscribe(
(params: Params) => { this.user.id = params['id']; this.user.name = params['name']; }
);
(params: Params) => { this.user.id = params['id']; this.user.name = params['name']; }
);
Environment: MS VS Code, bootstrap 3 and Angular 6
Download Project (zip): SampleRoutes
Sample 5
Simple Observable with RxJS Compat for old syntax
To use older way of importing things use rxjs-compat
> npm install --save rxjs-compat
With the above in place, take a look at the home controller. It is importing following two at the top
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/Rx';
and then look at the myNumbers Observable and its subscription routine. We are emitting fixed integers in an interval. Run the application and take a look at console development tools.
An observable takes 3 parameters
- Normal Data
- Error routine (optional)
- Complete routine (optional)
Now lets build a custom observable from scratch. It will fire every two seconds, four seconds and so on and will fail after 5 seconds. Take a look at the customObservable code in home controller.
The Observable create method takes an anonymous function. after creating the Observable, subscribe to it and run the application to see it in action in console.
At the end you must destroy your subscription, meaning unsubscribe by implementing ngOnDestroy. We need to clear the memory and space.
For built in observables, take a look at the user component. It is subscribing to ActivatedRoute. We don't need to explicitly unsubscribe here (like for custom observables) since angular takes care of this for us. Still good practice is to unsubscribe for these as well.
//simple observable subscription for myNumbers, we should always unsubscribe in ngOnDestroy
myNumbersSubscription: Subscription;
//custom observable, , we should always unsubscribe in ngOnDestroy
customObservableSubscription: Subscription;
ngOnInit() {
//create a simple observable, emit fixed integers in an interval
const myNumbers = Observable.interval(1000);
//subscribe to it
this.myNumbersSubscription = myNumbers.subscribe(
//normal data
(number: number) => {
console.log(number);
},
//error handling
() => {
//nothing for this example
},
//complete
() => {
//nothing for this example
}
);
//custom observable
const customObservable = Observable.create(
(observer: Observer
setTimeout(
() => {
observer.next('first package');
},2000);
setTimeout(
() => {
observer.next('second package');
},4000);
setTimeout(
() => {
observer.error('this does not work');
},5000);
setTimeout(
() => {
//this will never fire since the error above is firing at 5 seconds
observer.complete();
},6000
)
}
);
//subscribe to custom observable
this.customObservableSubscription = customObservable.subscribe(
//normal data
(data: string) => {console.log(data)},
//error
(error: string) => {console.log(error)},
//complete, not firing at this time
() => {console.log('completed!')},
);
}
ngOnDestroy(){
//destroy simple subscription
this.myNumbersSubscription.unsubscribe();
//destroy custom subscription
this.customObservableSubscription.unsubscribe();
}
Environment: MS VS Code, bootstrap 3 and Angular 6
Download Project (zip): SampleSimpleObservable01WithRxJsCompat
Sample 6
RxJS Subject - Built on above Simple Observable with RxJS Compat for old syntax
Subject is like a observable but it allows us to conveniently push it to emit new data. Note that Subject is Observable and Observer at the same time. Check the onActivated event in user.component.ts and compare it to observables in home.component.ts.
We'll create a new service called users.service.ts under app folder. Then provide this service by providing it in providers array in app.module.ts. Make sure to import import { UsersService } from './users.service'; as well.
This service will have a property userActived as new Subject. Make sure to import Subject.
import { Subject } from "rxjs/Subject";
export class UsersService{
userActivated = new Subject();
}
Then go to users.component.html and add a new button with click event
<button class="btn btn=primary" (click)="onActivated()">Activate</button>
After that go to users.component.ts and inject the service to use it via constructor and also make sure to import it. Note that we do not need to provide it here since we have provided it via app.modules.ts.
Then write onActivated event handler. Here call next on UsersService userActivated property and pass it a value. Note that Subject is a Observable and Observer at the same time.
We'll utilize this subject in app.component. Create two properties user1Activated and user2Activated and add to the template via string interpolation.
<a [routerLink]="['user', 1]">User 1 {{ user1Activated ? '(activated)' : '' }}</a>
<a [routerLink]="['user', 2]">User 2 {{ user2Activated ? '(activated)' : '' }}</a>
Then create two properties in app.component.ts
user1Activated = false;
user2Activated = false;
Make sure to inject UserSerive via constructor and to also implement ngOnInit
Since we have already set up obervable via user component
onActivated(){
this.usersService.userActivated.next(this.id);
}
In the app component we'll subscribe to it in ngOnInit and will make the appropriate flag true or false.
ngOnInit(){
this.usersService.userActivated.subscribe(
(id: number) => {
if(id === 1){
this.user1Activated = true;
this.user2Activated = false;
}
else{
this.user2Activated = true;
this.user1Activated = false;
}
}
);
}
Subject works like an EventEmitter. Consider using Subject when you want to use EventEmitter. EventEmitter works with .emit() where as Subject works with .next().
Run the app and click on User 1 and User 2 links and also click on Activate button and see the navigation getting changed accordingly.
Environment: MS VS Code, bootstrap 3 and Angular 6
Download Project (zip): SampleSimpleObservable02SubjectWithRxJsCompat
Sample 7
Observables without RxJs Compat
Sample is based on above Sample: 6 RxJS Subject - Built on above Simple Observable with RxJS Compat for old syntax
We'll remove the rxjs compat. Go to package.json and remove line
"rxjs-compat": "^6.2.1",
Then perform npm install
> npm uninstall --save rxjs-compat
If you do ng server, it will fail.
We can use rxjs 6 without the copat extra package. For this we will need to adjust our imports
In users.service.ts, we currenlty have
import { Subject } from "rxjs/Subject";
Instead import from rxjs only.
import { Subject } from "rxjs";
In the home.component.ts, we currently have
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import { Observer } from 'rxjs/Observer';
import { Subscription } from 'rxjs/Subscription';
Change to
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable, Observer, Subscription, interval } from 'rxjs';
import { map } from 'rxjs/operators';
We can't directly use the map function after these changes, instead use the pipe and pass the map to it. Map is an operator and it transforms the data. In this case it just multiplies the number by 2.
const myNumbers = Observable.interval(1000)
.map(
(data: number) => { return data *2;}
);
to
const myNumbers = interval(1000)
.pipe(map(
(data: number) => { return data *2;}
));
After these changes ng serve should compile without any issue.
Environment: MS VS Code, bootstrap 3 and Angular 6
Download Project (zip): SampleSimpleObservable04WithoutRxJsCompat