#httpmodule
Explore tagged Tumblr posts
Video
youtube
Node.js Tutorials for beginners in hindi | node.js http module | Part-8
0 notes
Text
No IFrame For You
No IFrame For You
Security isn’t easy, but its becoming more important. There’s lots of evidence explaining the dangers of missing any flaws. One of the items that got flagged on a project that allowed IFrames from any other site. The findings referenced the X-Frame-Options header. In my particular case, the business wanted to allow IFraming across domains. This ruled out using DENY or SAMEORIGIN. ALLOW-FROM would…
View On WordPress
#actionfilter attributes#allow-from#appsettings#deny#httpmodule#iframe#IIS#sameorigin#security#web.config#webforms#x-frame-options
0 notes
Text
Dot Net Core Interview Questions and Answers - Part 11:
Q104. What is Forwarded Headers Middleware in .Net Core? What should be their order in the middleware? Q105. What is the difference between MapGet() and Map() methods? Q106. What are the different built-in middlewares in ASP .Net Core? Q107. How can you create your own custom middleware and register it in the middleware in .Net Core? Q108. What is the difference between IMiddleware and IMiddlewareFactory Interface? When we should use Factory-Based Middleware in the .Net Core? Q109. What is the difference between synchronous and asynchronous middleware? Q110. How can you configure multiple middlewares in .Net Core? Q111. How can you configure the default file in the .Net Core Application? Q112. What is the difference between Httphandler, Httpmodules, and ASP .NET Core Middleware? Q113. How can you disable middleware in ASP .NET Core?
Please visit www.techpointfunda.com for more Interview Questions and Answers.
#dotnetcoreinterviewquestions#aspdotnetcore#coreinterviewquestionsandanswers#CSharpInterviewQuestionsAndAnswers#dotnetInterview#InterviewPreparation#InterviewQuestionsAndAnswers#techpointfundamentals#techpointfunda#techpoint#csharpprogramming
1 note
·
View note
Text
An overview of Angular
In this article, we are going to have a look at the Angular framework. Let's get into it!
Introduction
Nowadays, we have plenty of options to develop something that is ready for various platforms. However, Angular has made its way and it is now one of the most important actors. Let's see what it is and how it works.
We could jump right into the code of a project, but we would probably miss a few things. So, here, we are going to look at the architecture of Angular to understand the different concepts and elements this last one uses.
What is Angular?
Now, when we talk about Angular, we talk about Angular 2 or Angular 5. Angular is a complete rewrite of the AngularJS framework. Angular as a different approach from its predecessor.
Angular allows us to build applications across all platforms. It is an open-source platform that uses TypeScript. In a few words, TypeScript is a strict syntactical superset of JavaScript, and adds optional static typing to the language.
Architecture overview
Angular is written in TypeScript and it implements core and optional functionality as a set of TypeScript libraries that we can import.
An Angular application has, for building blocks, a thing called NgModules. An Angular app is defined by a set of NgModules. An app always has at least a Root Module that enables bootstrapping. An NgModule is made of Components. Every app has at least a Root Component.
Components, and things like Services, are just classes. They are, however, marked with decorators that tells Angular how to use them.
Angular provides a Router Service that helps us to define navigation paths among the different Views.
Modules
Angular apps are modular and this modularity system is called NgModules.
An NgModule defines a set of Components. An NgModule associate related code to form functional units. Every Angular app has a Root Module, conventionally named AppModule, which provides the bootstrap mechanism that launches the application.
Even if they are different and unrelated, NgModules, like JavaScript modules, can import functionality from other NgModules, and allow their own functionality to be exported and used by other NgModules. What we call Angular Libraries are NgModules.
We declare an NgModule by decorating our class with the "@NgModule" decorator. This decorator is a metadata object whose properties describe the module. The most important properties, which are arrays, are the following:
declarations - Components, Directives, and Pipes that belong to the NgModule
exports - the subset of declarations that should be visible and usable in the Components of other NgModules
imports - other modules whose exported classes are needed by Components declared in the NgModule
providers - list of the needed Services that, because they are listed here, become are available app-wide
bootstrap - the main application View, called the Root Component, which hosts all other app views. (only the Root Module should set this bootstrap property)
An NgModule provides a compilation context for its various Components. So, the Components that belong to an NgModule share a compilation context. NgModules define a cohesive block of functionality.
The Root Module of our application is the one that we bootstrap to launch the application. The application launches by bootstrapping the root AppModule. We also call it the entryComponent. The bootstrapping process creates the Components listed in the "bootstrap" array and inserts each one into the browser DOM. So, each bootstrapped Component is the base of its own tree of Components.
As we saw, we can have a Root Module, but we can have what we call Feature Modules. A Feature Module delivers a cohesive set of functionality focused on a specific application needs. We could do everything in the Root Module, but a Feature Module will help us partition our app into focused areas. However, the structure of a Feature Module is exactly the same as the one of a Root Module.
Down below, we can find an example of how could look an NgModule. Here, it is the AppModule:
// Importing Angular Libraries import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; // Importing the AppComponent import { AppComponent } from './app.component'; // Importing a custom feature module import { CustomFeatureModule } from './custom-feature-module/custom-feature-module.module'; // Declaring the Module @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, FormsModule, HttpModule, CustomerDashboardModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Components
A Component controls a patch of screen called a View. The logic of a Component is defined inside a class. Angular creates, updates, and destroys Components as the user moves through the application.
A Component is identified by the "@Component" decorator that has a set of properties. The most import properties are the following ones:
selector - tells how the component is referenced in HTML; in simple words, it corresponds to the HTML tag.
templateUrl - gives the path of the HTML template.
providers - an array of Dependency Injection Providers for Services that the Component requires.
Notice that instead of the "templateUrl" property, we could use the "template" property that lets us provide the HTML template inline.
A Component has a View and this last one is defined through an HTML template. This HTML file also contains some syntactic elements that are included in Angular.
A Component will typically look like so:
@Component({ selector: 'my-component', templateUrl: './my-component.component.html', providers: [ MyService ] }) export class MyComponent implements OnInit { // Some code }
Before going any further with Components, let's take a look at a few other elements to simplify some terms that we will use later.
Services
A Service is useful to define things that can't fit into a Component and find their reason to exist in the separation of concerns. A Service is a class with a well-defined purpose. For example, we should create a Service when two or more Components or other things need to access the same data or if we want to encapsulate interactions with a web server or if we want to define how to validate user inputs.
Services are Singletons, so there is only one instance of each Service we define. They are stateless objects that can be invoked from any Components. Their purpose is to help us to divide our application into small, different logical units that can be reused.
A Service is a simple class and could look like so:
export class Logger { log(msg: any) { console.log(msg); } error(msg: any) { console.error(msg); } warn(msg: any) { console.warn(msg); } }
Dependency Injection
Dependency Injection is a large subject. Dependency Injection, also called DI, is a Design Pattern in which one or more dependencies (Services) are injected into a dependent object (Client). This pattern allows us to implement a loosely coupled architecture by separating the creation of a client's dependencies from its own behavior.
We can apply this pattern when we want to remove knowledge of concrete implementations from objects, but also when we want to get a better testable code in isolation using mock objects.
The DI Pattern is commonly used to implement the Inversion of Control Principle, which in a few words, separates the what-to-do part of the when-to-do part. In other words, it is about letting somebody else handles the flow of control. It is based on the Hollywood Principle: "Don't call us, we'll call you".
Dependency Injection could be achieved by using the "constructor" of a class or "setter" methods. It can also be achieved with a Container that handles the instantiation of other objects.
In Angular, DI is widely used and we can take a moment to dig a little into it.
Angular uses its own Dependency Injection framework that basically uses three things:
The Injector, that exposes APIs. It is responsible for creating Service instances and injecting them into classes.
The Provider, that tells the Injector how to create an instance of a dependency.
The Dependency, the type of which an object should be created.
Angular has a Hierarchical Dependency Injection system. There is a tree of Injectors that parallels an application's Component tree. An application may have multiple Injectors. That means we can configure Providers at different levels:
For the whole application when bootstrapping it. All sub Injectors will see the Provider and share the instance associated with. It will always be the same instance.
For a specific Component and its sub Components. Other Components won't see the Provider.
For Services. They use one of the Injectors from the element that calls the Service chain.
When using DI with Angular, we will mainly see the "@Injectable" decorator. This decorator marks a class as available to Injector for creation.
In an Angular app, Components consume Services. A Component shouldn't create a Service. So, we inject the different required Services into the different Components. When Angular creates a new instance of a Component class, it determines which Services or other dependencies that Component needs by looking at the types of its constructor parameters. When Angular discovers that a Component needs a Service, it checks if the Injector already has any existing instances of that same Service. If an instance of that requested Service doesn't exist, the Injector makes one using the registered Provider and adds it to the Injector before returning the Service to Angular.
A Provider is a recipe for creating a dependency. We must at least register one Provider of any Service we want to use. It can be done in Modules or in Components. Doing this in a Module allows Angular to inject the corresponding Services in any class it creates and so the Service instance lives for the life of the app. By using a Component Provider we restrict the scope of the Service and so it will only be injected into that Component instance or one of its descendant Component instances. It means that Angular can't inject the same Service instance anywhere else. The lifetime of this Service will also be different: the Service instance will be destroyed when the Component instance is destroyed.
Here is how we can inject a Service in a Component:
import { Injectable } from '@angular/core'; import { Logger } from './logger'; @Injectable() export class Logger { log(msg: any) { console.log(msg); } error(msg: any) { console.error(msg); } warn(msg: any) { console.warn(msg); } }
logger.service.ts file
import { Component } from '@angular/core'; import { Logger } from './logger'; @Component({ selector: 'my-component', templateUrl: './my-component.component.html', providers: [ Logger ] }) export class HeroListComponent implements OnInit { constructor(private logger: Logger {} }
my-component.component.ts file
We could also do it with the Root Module like so:
@NgModule({ providers: [ Logger ] })
app.module.ts file
import { Component } from '@angular/core'; import { Logger } from './logger'; @Component({ selector: 'my-component', templateUrl: './my-component.component.html', }) export class MyComponent implements OnInit { constructor(private logger: Logger {} }
my-component.component.ts file
We can also imagine the a Service needs another Service:
import { Injectable } from '@angular/core'; import { Logger } from './logger.service'; @Injectable() export class MyService { constructor(private logger: Logger) { } }
Data Binding
Basically, data bindings allow properties of two objects to be linked so that a change in one causes a change in the other. It establishes a connection between the user interface and the underlying application. It defines a relationship between two objects: a source object that will provide data and a target object that will use the data from the source object. The benefit of data binding is that we no longer have to worry about synchronizing data between our Views and data source.
With Angular, the most common way to display a Component property is to bind that property name through interpolation. Interpolation is the estimation of a value or a set of values based on their context. It allows to evaluate a string containing one or more placeholders and to replace those placeholders with a computed and corresponding value. The context is typically the Component instance. So, basically, in Angular, to achieve this, we have to put the property name in the View enclosed in double curly braces. It will be something like so:
<h1>{{title}}</h1>
Most of the time, bindings are used to connect the visuals of an application with an underlying data model, usually in a realization of the MVVM Pattern (Model-View-ViewModel) or the MVC Pattern (Mode-View-Controller). In Angular, the Component plays the part of the Controller/ViewModel, and the template represents the View.
Angular provides many kinds of data binding. Binding types can be grouped into three categories distinguished by the direction of the data flow: source-to-view, view-to-source and two-way sequence: view-to-source-to-view. When we use binding types other than interpolation, we have to specify a target name that is the name of a property. It looks like an attribute name, but it is not. With data binding, we are not working with HTML attributes, but properties of DOM (Document Object Model) elements. Just to refresh our minds, we may say that attributes are defined by HTML and properties are defined by DOM and the responsibility of HTML attributes is just to initialize DOM properties. Later DOM properties can change, but HTML attributes cannot. Some DOM properties don't have corresponding attributes and some HTML attributes don't have corresponding properties. The target of a data binding is something in the DOM.
import { Component } from '@angular/core'; @Component({ selector: 'my-component', templateUrl: './my-component.component.html', }) export class MyComponent { imgSrc: String = 'path-to-image'; }
my-component.component.ts file
<img [src]="imgSrc">
my-component.component.html file
We often say that property binding is one-way data binding because it flows a value in one direction, from a Component's data property into a target element property. However, we are allowed to achieve something called two-way data binding that, for example, lets us display a data property and update that property when the user makes changes. We can do this by using the syntax "[(x)]".
We are also able to achieve event binding:
export class MyComponent { doSomething() { // some code } }
my-component.component.ts file
<button (click)="doSomething()">Do something</button>
my-component.component.html file
Input and Output
In a Component, we can use two decorators on properties: "@Input" and "@Output".
An Input property is a settable property. An Output property is an observable property. Input properties usually receive data values. Output properties expose Event producers.
Declaring an Input property would give something like so:
export class MyComponent { @Input() name: String; }
my-component.component.ts file
<my-component name="foo"></my-component>
my-component.component.html file
An Output property almost always returns an Angular EventEmitter. An EventEmitter allows us to emit a custom Event. It is helpful to pass a value to a parent Component. Let's say that we have something like this:
export class MyComponent { @Output() deleteItemRequest = new EventEmitter<Item>(); delete() { this.deleteItemRequest.emit(this.item) } }
my-component.component.ts file
<button (click)="delete()">Delete</button>
my-component.component.html file
As we can see, here, we use event binding. So, when the button is clicked, we call the "delete()" method. In the Component, we also declare an Output property that returns an EventEmitter and we declare its underlying type as "Item". So, when the "delete()" method is called, we use this EventEmitter to emit a new Event. In fact, it will emit an "Item" object.
So, we can now imagine that we have the following thing as a parent Component:
export class ParentComponent { deleteItem(item: Item) { // Some code } }
parent-component.component.ts file
<parent-component (deleteItemRequest)="deleteItem($event)"></parent-component>
parent-component.component.ts file
When the child Component emits its Event, the parent Component will use the result of this same Event with its own method.
Component Lifecycle Hooks
Angular manages the lifecycle of the different Components. Through different Hooks, it provides a way to perform actions when those different moments occur. We access to those moments by implementing one or more of the lifecycle Hook interfaces in the Angular core library. Each interface has a single Hook method whose name is the interface name prefixed with "ng".
Down below, we have an example of a Component using the "OnInit" interface:
export class MyComponent implements OnInit { ngOnInit() { // Some code } }
Communication between parent and child Components
There are a few ways to make a parent and child Component interact. One way is to inject the child Component into the parent as a ViewChild. This could be achieved like so:
import { ViewChild } from '@angular/core'; import { Component } from '@angular/core'; import { ChildComponent } from './child-component.component'; export class ParentComponent { @ViewChild(ChildComponent) private childComponent: ChildComponent; method1() { this.childComponent.childMethod1(); } method2() { this.childComponent.childMethod2(); } }
Another way to make a parent and child Component interact is to make them share a Service.
Directives
In Angular, there are three kinds of Directives:
Components - Directives with a template
Structural Directives - change the DOM layout by adding and removing DOM elements
Attribute Directives - change the appearance or behavior of an element, Component, or another Directive
We have already seen Components. They are the most common Directives.
Structural Directives change the structure of the View. They are things like "NgFor" or "NgIf". Here is an example of different Structural Directives:
<div *ngIf="character" class="name">{{character.name}}</div> <ul> <li *ngFor="let character of characters">{{character.name}}</li> </ul> <div [ngSwitch]="character?.size"> <app-big-character *ngSwitchCase="'big'" [character]="character"></app-big-character> <app-medium-character *ngSwitchCase="'medium'" [character]="character"></app-medium-character> <app-small-character *ngSwitchCase="'small'" [character]="character"></app-small-character> <app-character *ngSwitchDefault="'small'" [character]="character"></app-character> </div>
Attribute Directives are used as attributes of elements. They are things like "NgClass" or "NgStyle". Here is an example of different Attribute Directives:
<div [ngStyle]="currentStyles"> Some content. </div> <div [class.error]="hasError">Some error</div>
Let's make a little side note for the "NgModel" Directive that is part of the "FormsModule". This Directive helps us when we want to display a data property and update that property when the user makes changes through a form. Using this two-way data binding makes this easier. It will map the various fields of our form to our Data Model. It will ensure that the data in the View and the data in our Data Model are synced.
We can use this Directive like so:
export class MyComponent { name: string; }
my-component.component.ts file
<input type="text" [(ngModel)]="name" />
my-component.component.html file
We are also able to build Attribute Directives. We just have to create a class annotated with the "@Directive" decorator.
Pipes
Pipes are a way to operate some transformations over data before displaying them. Angular comes with several built-in Pipes. For example, we can have something like so:
<p>The character's birthday is {{ birthday | date:"MM/dd/yy" }}</p>
We are also able to create our own Pipes by using the "@Pipe" decorator and implementing the "PipeTransform" interface. This could be done like so:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'exponentialStrength'}) export class ExponentialStrengthPipe implements PipeTransform { transform(value: number, exponent: string): number { let exp = parseFloat(exponent); return Math.pow(value, isNaN(exp) ? 1 : exp); } }
Observables
Observables provide support for passing messages between Publishers and Subscribers in our application. An Observable can deliver multiple values of any type.
A Publisher must create an Observable instance. This object defines a function that is executed when a consumer calls the "subscribe()" method. This method, called the subscriber function, states how to get data to be published. To execute our Observable, we have to call its "subscribe()" method and pass it an Observer. This object implements the "Observer" interface and is responsible to handle the various notifications from the Observable.
To use Observables, we need to import the RxJS Library. RxJS is a library for reactive programming, which is a declarative programming paradigm where we program with asynchronous data streams. Data streams can be anything and we are so able to listen to them and react accordingly. A stream is a sequence of continuous Events ordered in time and it can emit three different things: a value of some type, an error or a "completed" value. Asynchronously, we capture these different emitted events by defining functions: one that will execute when a value is emitted, another that will execute when an error is emitted and another one that will execute when "completed" is emitted. The action of listening to the stream is named "subscribing". The various functions we define are the "Observers" while the stream is the "subject" or the "Observale". This is the Behavioral Design Pattern called the Observer Pattern. We also have to deal with the "Operators" which are the various pure functions, functions that always evaluate the same result value when we give them the same argument value, that will let us work on the emitted values.
This kind of programming is really helpful when we have to deal with various UI Events related to data Events. It helps us to achieve real-time apps.
Let's imagine that we have a Service that is responsible to fetch users:
import { Observable } from 'rxjs/Rx' import { Injectable } from '@angular/core' import { Http, Response } from '@angular/http' @Injectable() export class UsersService { constructor(public http: Http) {} public fetchUsers() { return this.http.get('/api/users').map((res: Response) => res.json()) } }
Our method "fetchUsers()" returns an Observable, our subject. So, we can subscribe to our subject like so:
import { Component } from '@angular/core' import { Observable } from 'rxjs/Rx' import { UsersService } from './users.service' import { User } from './user' @Component({ selector: "my-component", templateUrl: "./my-component.component.html", providers: [ UsersService ] }) export class MyComponent { public users: Observable<User[]> constructor(public usersServce: UsersService) {} public ngOnInit() { this.users = this.UsersService.fetchUsers() } }
In our template file, we have to do the following things:
<ul class="user-list" *ngIf="(users | async).length"> <li class="user" *ngFor="let user of users | async"> {{ user.name }} </li> </ul>
We may also want to create an Observable from a Promise. We can do it like so:
const data = fromPromise(fetch('/api/endpoint'));
This create an Observable. To subscribe, we have to do the following thing:
data.subscribe({ next(response) { console.log(response); }, error(err) { console.error('Error: ' + err); }, complete() { console.log('Completed'); } });
Here, we achieve the process of subscription and as we can see, we define the three functions that we talked about a little earlier.
Forms
We can use Angular event bindings to respond to Events that are triggered by user input. For example, we can imagine the following situation:
export class MyComponent { values = ''; onKey(event: any) { this.values += event.target.value; } }
my-component.component.ts file
<input (keyup)="onKey($event)"> <p>{{values}}</p>
my-component.component.html file
Angular has also a whole "Form" library that helps us with many things. We can, for example, use it to add some validation rules to our forms.
<input id="name" name="name" class="form-control" required minlength="4" [(ngModel)]="user.name" #name="ngModel" > <div *ngIf="name.invalid && (name.dirty || name.touched)" class="alert alert-danger"> <div *ngIf="name.errors.required"> Name is required. </div> <div *ngIf="name.errors.minlength"> Name must be at least 4 characters long. </div> </div>
Here, we start by defining a input with a few rules. As we can see, we export the "ngModel" Directive to achieve two-way data binding. We also export the form control's state to a local variable "#name". Then, we check if the control has been touched and we display different errors if there are some.
With Angular, we also have the ability to dynamically generate forms. To achieve this, we have to create objects derived from the base class "QuestionBase" and that represents the various controls of our forms. We can then treat them through a Service that will build the form and return it as a "FormGroup" object.
Routing & Navigation
In Angular, the Router allows navigation from one View to the next. The Router interprets a browser URL to navigate to a client generated View and, if needed, pass optional parameters. The Router can be bound to links or it can be used in response to some actions.
To use the Router correctly, we need to add a "base" element to our "index.html" file. We also need to import the Router Module. In our "app.module.ts" file, we can do the following thing:
import { RouterModule, Routes } from '@angular/router'; const appRoutes: Routes = [ { path: 'characters', component: CharactersComponent }, { path: 'character/:id', component: CharacterDetailComponent }, { path: '', redirectTo: '/characters', pathMatch: 'full' }, { path: '**', component: PageNotFoundComponent } ]; @NgModule({ imports: [ RouterModule.forRoot(appRoutes) ] }) export class AppModule { }
As we can see, we define our navigation Routes in the array "appRoutes" and we pass this array to the "RouterModule". We can now use the "RouterOutlet" Directive, that marks where the Router displays a View, to create some kind of navigation menu:
<nav> <a routerLink="/characters" routerLinkActive="active">Characters</a> </nav> <router-outlet></router-outlet>
After the end of each successful navigation lifecycle, the Router builds a tree of "ActivatedRoute" objects that make up the current state of the Router. We are able to access the current "RouterState" from anywhere in the application using the Router Service and the "routerState" property.
Conclusion
Through this article, we got a brief overview of the Angular technology. It was more a theoretical post than a practical example. Of course, we didn't cover entirely each subject and there are plenty of other subjects that we could have explored like Unit Testing or E2E Testing. Now, however, we have enough knowledge of Angular to start a project and to dig deeper into this framework.
One last word
If you like this article, you can consider supporting and helping me on Patreon! It would be awesome! Otherwise, you can find my other posts on Medium and Tumblr. You will also know more about myself on my personal website. Until next time, happy headache!
8 notes
·
View notes
Quote
http://computer.seosocialnews.info/story.php?title=vermeer- http://noida.locanto.net/ID_2216039109/homage-vermeer.html https://www.classifiedads.com/training_education/2x563spsg1334 https://www.indiae.in/homage-of-vermeer-F120CC50418D842 http://www.adsciti.com/services/travel-agents/vermeer-296498.htm http://www.freeadsciti.com/services/travel-agents/vermeer-900400.htm http://wikidok.com/vehicles/trucks-commercial-vehicles http://www.classifiedsciti.com/services/travel-agents/vermeer-911119.htm http://www.usadsciti.com/services/travel-agents/vermeer-238115.htm http://www.postfreeadshere.com/services/travel-agents/vermeer-200021.htm http://www.freeadsbook.com/services/vermeer-515210.htm http://adsblue.com/services/travel-agents/vermeer-545988.htm https://noida.adeex.in/homage-of-vermeer-music-in-vimeo-id-1817433 https://www.adpost.com/in/business_opportunities/426089/?session_key=98ac7d285767444093d7b0c6fd3a48b9 https://penzu.com/p/fe079a7b http://bullbulla.blogspot.in/2018/03/vermeer.html https://medium.com/@sunildubey_47607/vermeer-fc5e086c78eb https://sunilwebtrackker.tumblr.com/post/171582206134/vermeer https://onlinetrainingclassesindia.wordpress.com/2018/03/06/vermeer/ http://sunilwebtrackker.tblog.com/vermeer-r-n-r-nvermeer-mainly-painted-the-interiors-of-the-home-almost-all-of-his-paintings-are-appa/18g4nagwoe96o http://sunil-dubey.skyrock.com/3309786182-Vermeer.html https://raavan78645.wikispaces.com/home https://raavanvermeer.tumblr.com/post/171582611927/vermeer https://raavanvermeer.tumblr.com/ https://issuu.com/sunildubey7/docs/presentation1.pptx https://www.scribd.com/presentation/373083131/vermeer http://www.slideboom.com/presentations/2047736/vermeer http://www.powershow.com/view0/89840d-YmI2Z/Vermeer_powerpoint_ppt_presentation http://www.authorstream.com/Presentation/ironwebtrackker-3390208-vermeer/ https://ibb.co/jeytHn https://ibb.co/iMXaV7 https://ibb.co/eO62A7 https://ibb.co/eunncn https://ibb.co/e1iScn https://ibb.co/album/etD7Ov https://in.pinterest.com/pin/768919336353461436/ https://brucejon.smugmug.com/Vermeer/ https://imgur.com/gallery/qUmLe http://www.fotolog.com/brucejon/128000000000037203/ http://tinypic.com/m/k4a6og/4 https://500px.com/photo/248371289/1-jpg-by-bruce-jon https://weheartit.com/entry/308465845?context_set=142144614-no-place-like-home&context_type=collection http://www.ipernity.com/doc/2375066/46338932 https://youpic.com/image/12572369/ https://www.lomography.com/homes/brucejon/photos/22570062?order=trending https://photos.google.com/photo/AF1QipNi2QE0z1pEFjVZABSmpfh1N7V8v4eg9n9RIJtX https://photos.app.goo.gl/89zAabgMnv0vKLu23 https://www.lomography.com/homes/brucejon/photos/22570062?order=trending https://www.yogile.com/l0y4dz95#41m http://www.fotothing.com/bruceamj/photo/9a95a2d1e36fb6f79d54862dafc4f22e/ http://forum.fotothing.com/topic/18020/0#end https://www.blogger.com/comment.g?blogID=6459805915085212026&postID=1237174639347835510&page=1&token=1520329507668 https://download-aplikasinya.blogspot.in/2012/09/tutorial-menjalankan-script-php-di-blog.html#comment-form https://helpingdotnet.blogspot.in/2015/05/httphandler-and-httpmodule-in-aspnet.html#comment-form https://kishorecboracleapps.blogspot.in/2015/04/oracle-adf-beginner-links.html#comment-form https://oracleebspro.blogspot.in/2013/02/oracle-apps-r12-architecture-technical.html#comment-form https://phpsollutions.blogspot.in/2017/01/angularjs-interview-questions.html https://onlydifferencefaqs.blogspot.in/2012/08/dotnet-differences-list.html#comment-form https://shahiddba.blogspot.in/2013/07/dba-interview-questions-with-answer.html#comment-form http://www.technotactics.in/2013/05/similarities-lives-harsh-agarwal-steve-jobs/#comment-56139 https://www.blogger.com/comment.g?blogID=2202766463251903159&postID=217926372036189789&page=1&token=1520329677326 https://maximodev.blogspot.in/2016/05/industrial-internet-of-things-iot-iiot.html#comment-form https://www.blogger.com/comment.g?blogID=1882165764506799121&postID=4622110048121309611&page=1&token=1520330299304 https://learningviacode.blogspot.in/2013/08/hibernate-cache-framework.html#comment-form https://salesforceworld.blogspot.in/2017/06/trailblazers-released-16-new-modules.html#comment-form https://hadoopspark.blogspot.in/2017/03/89-spark-standalone-cluster.html#comment-form https://tomstechnicalblog.blogspot.in/2016/10/kotlin-for-data-science.html#comment-form http://www.technotactics.in/2013/05/similarities-lives-harsh-agarwal-steve-jobs/#comment-56139 https://maximodev.blogspot.in/2016/05/industrial-internet-of-things-iot-iiot.html#comment-form https://www.blogger.com/comment.g?blogID=1882165764506799121&postID=4622110048121309611&page=1&token=1520330299304 https://learningviacode.blogspot.in/2013/08/hibernate-cache-framework.html#comment-form https://salesforceworld.blogspot.in/2017/06/trailblazers-released-16-new-modules.html#comment-form https://hadoopspark.blogspot.in/2017/03/89-spark-standalone-cluster.html#comment-form https://tomstechnicalblog.blogspot.in/2016/10/kotlin-for-data-science.html#comment-form https://wannabedatarockstar.blogspot.in/2016/12/automatically-parse-dates-in-any.html#comment-form https://qualitythoughtchefpuppetdocker.blogspot.in/2017/03/chef-new-material-03302017.html#comment-form https://javabasictoadvanced.blogspot.in/p/preface.html#comment-form https://www.bloggingpages.com/2013/02/how-to-use-google-dorks-for-link-building.html#comment-21784 https://pankajtiwarii.blogspot.in/2013/11/aspnet-interview-question-and-answer.html#comment-form https://hadoopspark.blogspot.in/2017/03/89-spark-standalone-cluster.html#comment-form https://www.blogger.com/comment.g?blogID=1418589822970159580&postID=2589309645656365362&page=1&token=1520329606779&isPopup=true https://thevizioneer.blogspot.in/2014/03/tableau-30-for-30.html#comment-form https://2k8618.blogspot.in/2009/04/inheritance-example-3-room-java.html#comment-form https://functionalguy.blogspot.in/2017/04/item-classification-for-gst-regime.html#comment-form https://aspdotnet-kishore.blogspot.in/2016/11/interview-questions-for-3-years-of_22.html#comment-form http://hadoopguru.blogspot.in/2013/07/hadoop-servers.html https://www.blogger.com/comment.g?blogID=4132348204535316816&postID=7299525481460788701&page=1&token=1520331801095 https://databrit.blogspot.in/2016/01/makeovermonday-data-science-degrees-and.html#comment-form https://automationtestingutilities.blogspot.in/p/blog-page_11.html#comment-form https://seleniumworks.blogspot.in/2017/04/how-to-use-json-file-as-object.html#comment-form https://hadooped.blogspot.in/2013/06/apache-sqoop-part-3-data-transfer.html#comment-form https://manoharbabuapps.blogspot.in/2015/06/passing-multiple-values-for-single.html#comment-form https://ermanarslan.blogspot.in/2015/05/ebsssl-supportcertification-for-sha2.html#comment-form https://snehalthakur.blogspot.in/2017/02/what-is-big-data-big-data-is-term-that.html#comment-form https://angularjsinterviewquestionspdf.blogspot.in/2017/02/50-top-angularjs-interview-questions.html#comment-form https://rathinamcomputerscience.blogspot.in/2017/02/international-conference-on-data.html#comment-form https://crsktech.blogspot.in/2015/01/contact-us-crsktech-java-training.html#comment-form https://onlinehardware.blogspot.in/2011/09/computer-hardware-networking-tutorials.html#comment-form https://nvprojects.blogspot.in/p/5-best-site-to-download-projects-free.html#comment-form https://javaeeeee.blogspot.in/2017/02/angularjs-tutorial-angularjs-controller.html#comment-form https://www.blogger.com/comment.g?blogID=2001595886969899899&postID=3035250837659633227&page=2&token=1520335986797 https://dinesh-malav.blogspot.in/2015/05/image-processing-using-opencv-on-hadoop.html#comment-form https://aspnet-jitendra.blogspot.in/2013/07/aspnetmvcjquery-interview-questions-and.html#comment-form https://automationtricks.blogspot.in/2015/02/what-is-implicit-explicit-fluent-wait.html#comment-form https://sapficousa.blogspot.in/p/sap.html#comment-form https://chenchioracleebsappsr12.blogspot.in/p/blog-page_4.html#comment-form https://pkkjava.blogspot.in/p/angularjs-interview-questions.html#comment-form https://springjavatutorial.blogspot.in/2014/07/differences-between-hashtable-and.html#comment-form https://penzu.com/p/73f36760 https://medium.com/@sunildubey_47607/vermeer-402edb1d9685 https://sunilwebtrackker.tumblr.com/post/171615107059/vermeer https://onlinetrainingclassesindia.wordpress.com/2018/03/07/vermeer-2/ http://sunil-dubey.skyrock.com/3309833086-Vermeer.html http://sunilwebtrackker.tblog.com/vermeervermeer-mainly-painted-the-interiors-of-the-home-almost-all-of-his-paintings-are-apparently-i/2nxvanwh3ayo http://bullbulla.blogspot.in/2018/03/vermeer_6.html http://www.usnetads.com/post/post-free-ads-op.php http://www.ukfreeads.ws/view/item-1069513-sunildubey.html http://www.usnetads.com/view/item-129759689-Vermeer.html http://www.canetads.com/post/post-free-ads-op.php http://www.innetads.com/post/post-free-ads-op.php https://www.postallads4free.com/moving_storage-ad535182.html http://www.ukadslist.com/post/post-free-ads-op.php http://www.aufreeads.com/post/post-free-ads-op.php http://www.getjob.us/usa-jobs-view/job-posting-651894-vermeer.html https://adclassified.in/52276/vermeer.html https://www.click.in/delhi/homage-to-vermeer-johannes-vermeer-c123-v29323174#vp1 https://www.indiae.in/vermeer-to-homage-F120CC5041DD046 https://www.bavun.in/_delhi/vermeer-a297864.html http://www.4ufreeclassifiedads.com/192/posts/153-Taxi-Business-/6408--New-computer-technologies-hybrid/89565-Vermeer.html https://aimotion.blogspot.in/2011/10/machine-learning-with-python-linear.html#comment-form http://blog.getmantra.com/2012/05/mantra-lexicon-in-10-languages.html#comment-form https://smallerseo.blogspot.com/p/high-pr-classified-submission-sites.html#comment-form http://embedded-systems-training-d.simplesite.com/ http://www.colorvfx.com/Blog/wp-comments-post.php http://digitalmarketingprofs.in/blog/top-free-dofollow-article-submission-sites-list-for-seo-2017/#comment-1294 https://www.blogger.com/comment-iframe.do?loginRedirect=5mTDAWIBAAA.TfAX3YgDYpIci1-OH2TwHXbGNyqse9zKLNtBO7Pq_Sw.QpyRB9OkvibdTbyEAat56w&pli=1 https://developers.facebook.com/docs/plugins/comments http://www.wellnessspadelhi.in/blog/lomi-lomi-massage-new-delhi/#comment-1733 https://nicedealsdelhi.blogspot.in/2017/12/full-body-to-body-massage-in-kailash-colony-delhi.html http://www.wellnessspadelhi.in/blog/female-to-male-body-to-body-massage-centers-south-delhi/#comment-1734 https://www.blogger.com/comment.g?blogID=5416308222584724787&postID=133088233403632702&page=2&token=1520420489458&isPopup=true http://www.nicedeals.co.in/blog/deep-tissue-massage/#comment-1176 https://talkmetech.com/free-movie-downloading-websites-2017/#comment-1602 http://www.timesofsuccess.com/top-20-quotes-to-unleash-your-motivation/#comment-2616 https://developers.facebook.com/docs/plugins/comments http://doablefinance.com/how-to-improve-your-credit-score-starting-today/comment-page-1/?captcha=failed#comments https://updateseourls.blogspot.in/2016/11/top-free-video-sharing-websites.html#comment-form http://www.freevpnsdownload.com/chrome/ultrasurf-vpn-chrome-extension-download.html#comment-1137 http://www.nicedeals.co.in/blog/best-body-massage-centres-delhi/#comment-1177 http://www.kuchjano.com/blog/high-pr-blog-commenting-sites-list/#comment-19103 http://www.wellnessspadelhi.in/blog/special-discounts-full-body-massage-moti-nagar-delhi/#comment-1735 https://www.newszoom.com/celebs-entertainment/celebrities-really-make-difference/#comment-118495 http://www.nicedeals.co.in/blog/simple-effective-body-massage-instruction-home/#comment-1178 http://www.tendtoread.com/social-bookmarking-sites-list-with-high-domain-authority/#comment-1106 https://developers.facebook.com/docs/plugins/comments http://www.wellnessspadelhi.in/blog/massages-hot-stones/#comment-1736 https://www.shoutmeloud.com/verified-blog-directories-free-blog-listing.html#comment-1806928 http://www.wellnessspadelhi.in/blog/massage-relaxing-healing-effects/#comment-1737 http://www.nicedeals.co.in/blog/best-deals-discount-coupons-full-body-massage-delhi/#comment-1179 http://makeupobsessedmom.com/wp-comments-post.php?wpe-comment-post=staciehamilton https://www.gsmarena.com/nickname.php3?sSource=/postopinion.php3?idPhone=8393#_=_ http://www.nicedeals.co.in/blog/full-body-massage-spa-centers-saket-delhi/#comment-1182 http://www.childrenstheatreplays.com/blog/The-Story-of-ArtReachs-School-Play-The-Jungle-Book--detail.htm?post=1#respond https://developers.facebook.com/docs/plugins/comments http://www.wellnessspadelhi.in/blog/hot-stones-massage/#comment-1739 http://www.thakurblogger.com/best-free-directory-submission-sites-list/#comment-9189 https://www.blogger.com/comment.g?blogID=5006505084971049337&postID=3697237971990062640 http://disq.us/p/1qp84r5 https://www.prdaily.com/Main/Articles/23228.aspx https://developers.facebook.com/products/social-plugins/comments/?utm_campaign=social_plugins&utm_medium=offsite_pages&utm_source=comments_plugin http://www.carwash.org/get-connected/ica-blog/ica-car-wash-blog/2015/05/28/new-vehicle-technologies---update http://www.bloggersideas.com/free-high-pr-directories-submission-sites-list/#comment-174607 http://www.nicedeals.co.in/blog/foot-reflexology-delhi-ncr/#comment-1183 http://www.wellnessspadelhi.in/blog/good-aroma-therapy-massage/#comment-1740 https://genderpopculture.blogspot.in/2013/10/participate-in-international-day-of.html#comment-form http://disq.us/p/1qp8c58 http://www.nicedeals.co.in/blog/full-body-to-body-massage-centres-in-lajpat-nagar-delhi/#comment-1184 https://www.esds.co.in/blog/social-media-marketing-for-online-business/#sthash.WBJi3ytg.BrwZBL9O.dpbs https://listofvideosharingsites.blogspot.in/2012/12/list-of-video-sharing-sites.html#comment-form https://youngadventuress.com/2013/03/istanbul-turkish-bath.html/comment-page-17#comment-435755 http://www.nicedeals.co.in/blog/facts-about-massage/#comment-1185 http://disq.us/p/1qp8qcc https://microisvjournal.wordpress.com/2007/11/19/rails-seo-tips-90-completed/#comment-64967 https://text-marketing.blogspot.in/2011/10/sms-marketing-benefits.html#comment-form https://internetmarketingblog101.com/4-tips-on-how-to-manage-your-remote-marketing-team/#comment-14968 https://nicedealsdelhi.wordpress.com/2017/08/28/full-body-to-body-massage-in-patel-nagar-delhi-by-female/comment-page-1/#comment-36 https://developers.facebook.com/docs/plugins/comments http://www.wellnessspadelhi.in/blog/full-body-body-massage-near-rajiv-chowk-delhi-female-male/#comment-1750 http://www.sociopathworld.com/2014/11/worse-than-psychopath.html#comment-form
0 notes
Text
Nestjs发送x-www-form-urlencoded风格的请求
Nestjs的Http模块
Nestjs的HttpModule模块打包了Axios并且暴露出HttpService接口,HttpService将Axios数据转换为Obervable并返回。比如,HttpService的Post方法在Nestjs源码中是这样写的。
post<T = any>( url: string, data?: any, config?: AxiosRequestConfig, ): Observable<AxiosResponse<T>> { return defer(() => this.instance.post(url, data, config)); }
默认情况下,HttpService发送的是JSON风格的请求,但是我们难免要和一些x-www-form-urlencoded风格的API打交道…
View On WordPress
0 notes
Text
Update Angular 7 to Angular 8
Update Angular 7 to Angular 8
Here is the latest release of Angular 8.0.0. This is one of the major release for entire platform, which includes Angular Framework, Angular Material and the CLI. In this blog, we will learn how to update your angular 7 to 8.
Before Update
If you are using HttpModule, then change it to HttpClientModule.
If you are using Http service, then change it to HttpClient Service.
Make sure you are…
View On WordPress
0 notes
Text
Angular Best Practices – Make Angular Application Development Easier
Making an Angular application is not enough. Keeping the code simple and well-maintained is equally important. For doing so, you need to stick to some of the Angular best practices. Not does it only helps in making the application cleaner but also boosts the performance of the same.
Angular boasts charting on the list of top 10 web development frameworks in 2018 as the leading front-end framework. Though Angular is one of the leading web application frameworks, it can also be used for building native mobile and desktop applications.
Considering the popularity and importance that Angular has accumulated, now is the best time to learn Angular if you haven’t done it already. Anyways, if you are already developing apps using Angular then must know how to do it better to remain competitive in the rapidly-changing realm of programming.
As such, we are here to share with you some of the best Angular practices suggested by experts. In order to make the most out of this article, you need to have at least a basic understanding of Angular. Considering you have that, let’s advance to the list of 12 best practices for Angular development.
Angular Best Practices
1. Add Caching Mechanisms
Simply, having a caching mechanism in place avoids unwanted API calls. Responses from some of the API calls don’t change at all. In such scenarios, adding a caching mechanism allows for storing the specific value from the API.
Adding caching mechanisms ensures that the same information is not downloaded time and over again. Moreover, making the API calls only when required and avoiding duplication results in a speed boost for the application. This is because there is no need to wait for the network.
2. Benefit from Lazy Loading
Lazy loading is loading something only when it is required. Whenever possible, try to lazy load the modules in the application. The benefit is twofold. First, it reduces the size of the application and second, as only the module that is required is loaded and not the unrequired ones, application boot time improves.
3. Deploy the Right Flattering Operator
Instead of using a multitude of operators when a single operator can suffice reduces the code size. As different types of operators handle observables in different ways, deploying the incorrect operator might lead to unwelcome application behavior.
Therefore, it is important to use the right flattering operator, such as concatMap and mergeMap, while dealing with observables.
4. Don’t Forget to Make Use of Angular CLI
It is highly recommended to make use of the Angular CLI while developing an Angular project. There are several reasons for this, including a boost in productivity. Angular CLI flaunts an enormous set of commands for completing a number of tasks.
Not only the Angular CLI creates components faster but also automatically references the same into their own modules. Moreover, it ensures compliance with the naming convention so that you don’t have to worry about doing it on your own.
5. Don’t Miss Out a Chance to Use Lifecycle Hooks
Whenever possible, use lifecycle hooks. Any component has a lifecycle, which is managed by Angular. Angular creates, renders, creates children, and renders children of components. Further, it checks when a component’s data-bound properties change and penultimately destroys it before finally removing the same from the DOM.
Lifecycle hooks provide the visibility into such key life moments as well as the ability to act when they occur. Some of the lifecycle hooks and their desirable uses include:
ngOnChanges () – Used for executing logic inside child components prompted by the modification of decorator parameters
ngOnDestroy () – Used for the need to perform a cleanup of resources when the component is destroyed
ngOnInit () – Used when some data is required to be fetched from a database as soon as the component is instantiated
Know more about Lifecycle hooks.
6. Ensure Using Lint Rules
In order to avoid doing something that can potentially lead to the rise of some issue later, Angular have lint rules. When a lint rule is in place and you do something wrong, an error will quickly pop-up and save the day for you. You can easily configure various lint rules in the tslint.json file.
Using lint rules in the code enforces consistency in the application as well as enhances readability. Some of the lint rules even come equipped with fixes for resolving the very issues that they correspond to. Moreover, you can write your own lint rules using TSQuery.
7. Isolate API Hacks
Several Angular APIs are plagued by bugs and hence, require fixes. However, it is better to isolate API hacks in one place rather than adding them to the components where they are required. The API hacks can be isolated in a service and used from the component.
But, why should you do it? Because doing so keep the hacks stay closer to the API. In addition to having all the hacks at one place, which makes fixing them easier and convenient, the action reduces the total code that is dealing with the unhacked code.
8. Keep your Application DRY (Do not Repeat Yourself)
Ensure that the same code is not copied in multiple sections of the complete codebase. In some cases, it might be required to change some logic in a particular code section. However, having identical code jotted down in multiple locations means that the change needs to be made at each and every section.
In addition to being a redundant job, this can lead to potential bug occurrences. Having a specific code at only one location not only makes the testing process easier but also improves application speed and performance.
9. Switch to HttpClient from HttpModule
Past Angular 4.3, there is a better way for handling HTTP requests via the HttpClient library. Although the HttpModule library is adequate for handling HTTP requests, it is highly recommended to make a switch to the HttpClient.
This is because aside from all the functionality, using HttpClient brings a number of benefits to the table. For instance, the HttpErrorResponse class in the HttpClient library facilitates error handling. Additionally, HttpClient grants access to interceptors, which allow intercepting HTTP requests, and offers the ability to listen to progress events.
10. Unsubscribe from Observables
While subscribing to observables, ensure that appropriate unsubscribes to the same are also made. As the observable stream is left open, such as after a component is destroyed or the user has navigated to some other page, not unsubscribing from observables might lead to undesired memory leaks.
So, how to unsubscribe from observables? Simple, by using operators such as take and takeUntil. Formulating a lint rule for the detection of observables that aren’t unsubscribed is highly recommended.
11. Use The trackBy Function
Using the trackBy function with the ngFor directive for looping over an array in templates return a unique identifier for each item in the array. When an array is changed, Angular re-renders the complete DOM tree. However, this isn’t the case when using the trackBy function.
The trackBy function allows Angular to know those specific elements that have changed. Hence, it will only make DOM changes for that particular element or set of elements.
12. When Using RxJs Operators, Use Pipeable Operators
This enables benefitting from the tree-shakeable ability of pipeable operators. Simply, it means that rather than the entire code, only the code that is necessary for execution will be included when these operators are imported. Moreover, another advantage is that it makes the identification of unused operators in the files easier.
Let’s Wrap it Up!
Developing applications is a craft and there’s always some room for improvement. Adhering to the aforementioned Angular best practices will make your Angular application development life easier. The less buggy your Angular application is, the better is the chances for performance and productivity to mushroom.
The official Angular style guide is very important for any web developer looking to champion in the craft of Angular development. If you haven’t gone through it yet, now might be a good time to do so. Check it here!
The post Angular Best Practices – Make Angular Application Development Easier appeared first on The Crazy Programmer.
0 notes
Text
Using Providers and HTTP Requests in a NestJS Backend
In the previous tutorial, we covered setting up a simple NestJS server that communicated with an Ionic application. All we have done so far is create a simple controller in NestJS that responded with some dummy message data. At the moment, it looks like this:
import { Controller, Get, Param } from '@nestjs/common'; @Controller('messages') export class MessagesController { @Get() getMessages(){ return { message: 'In a real example, I would return all of the messages' } } @Get(':id') getMessage(@Param('id') id){ return { message: `In a real example, I would return the message with an id of ${id}` } } }
The purpose of the previous tutorial was to introduce you to the basic structure of a NestJS project and get some simple communication happening between the backend and the front end.
In this tutorial, we will be aiming to cover two more concepts:
Using Providers
Making HTTP Requests
If you are coming from an Ionic/Angular background, then you could consider the Controllers in a NestJS backend to be similar in concept to the pages/views in your Ionic applications. Like pages, we should aim to keep our controllers as “light” as possible. The main role of a controller is to “direct traffic” – we should not assign too much “work” to a controller, it should just listen for the incoming requests, outsource the work that needs to be done, and then send a response to the request.
In that sense, it is a good idea to utilise “providers” in a NestJS application to do the heavy lifting for us. This way, a controller can make a request to a provider to do some work, rather than doing the work itself. This is much the same as we would have our pages in an Ionic/Angular application makes requests to a provider rather than do the work itself.
As an example, we will be modifying our existing server to fetch some data from a real API rather than just returning a string as dummy data. In the course of doing this, we will also need to learn how to make HTTP requests, as we will be launching an HTTP request from the provider that we create.
We will be using the API that quotesondesign.com provides to pull in some quotes to the application. The general process that we will be creating is:
The Ionic application makes a request to our NestJS backend
The controller that listens for that request will make a call to our provider
The provider will make a request to the API and return the data to the controller
The controller will return the data to the Ionic application
Why not just consume the API directly from the client?
Technically, we probably could just make an HTTP request from our Ionic application directly to the API for the same result. For example, in our Ionic application (or whatever kind of client-side tech you happen to be using) we could do something like this:
this.http.get('http://quotesondesign.com/wp-json/posts/2463).subscribe((response) => { console.log(response); });
Assuming that this particular API supports CORS, this would work just fine. We won’t be doing this, though. In this tutorial, we will be making a request to our NestJS server to load the data into the application instead (and the server will handle making the request to the Quote API), e.g:
this.http.get('http://localhost:3000/messages').subscribe((response) => { console.log(response); });
There can be benefits to proxying the request through our own server (e.g. if the API we wanted to use did not support CORS). However, what the service does is beside the point anyway – the point of this tutorial is to demonstrate how to use a provider in NestJS to “do work”, and I wanted a simple example to demonstrate the general idea.
In a more realistic/complex example, we might use the provider to handle requests that need to be handled on the server side. Perhaps a request to a MongoDB database, performing some authorisation logic, or handling uploading or downloading files. We will get to the more complex stuff in future, but for now, let’s just keep it basic.
Before We Get Started
Last updated for NestJS 5.0.0
This tutorial continues on from the last tutorial, which covered setting up a basic Ionic application using NestJS as the backend. You do not need to use Ionic/Angular in order to understand this tutorial, you could be using different tech on the front-end, but the tutorial is written with Ionic/Angular developers in mind. Many of the concepts in NestJS are the same as those in Angular, and this tutorial assumes a basic level of understanding of those Angular concepts.
Creating the Provider
The first thing we are going to do is add the provider to our application.
Run the following command to generate the provider:
nest g service services/quotes
By using this generate command, the provider will automatically be added to the imports in app.module.ts, which is required in order to use the provider.
After you have run the command, you will find the basic outline of the provider in src/services/quotes.service.ts.
Making an HTTP Request
The main role of our provider will be to perform an HTTP request and return that data to the controller. We are going to implement three different methods in the provider:
A method to return all of the quotes
A method to return a specific quote by id
A method to return a random quote
Before we can make any HTTP requests, we will need to set up the HttpModule in our NestJS application (just like we would need to set up the HttpClientModule in Angular).
Modify src/app.module.ts to reflect the following:
import { Module, HttpModule } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { MessagesController } from './messages/messages.controller'; import { QuotesService } from './services/quotes.service'; @Module({ imports: [HttpModule], controllers: [AppController, MessagesController], providers: [AppService, QuotesService], }) export class AppModule {}
We will also need to inject the HttpService into the provider.
Modify src/services/quotes.service.ts to reflect the following:
import { Injectable, HttpService } from '@nestjs/common'; import { map } from 'rxjs/operators'; @Injectable() export class QuotesService { constructor(private http: HttpService){ } }
Now we will be able to launch HTTP requests through this.http. Notice that we are also importing the map operator here. When we run our HTTP requests we don’t want to return the entire response object, we just want to return the data. We will be using the map operator to modify that response into the format we want. Now, let’s add our methods.
Modify src/services/quotes.service.ts to reflect the following:
import { Injectable, HttpService } from '@nestjs/common'; import { map } from 'rxjs/operators'; @Injectable() export class QuotesService { constructor(private http: HttpService){ } getQuotes(){ return this.http.get('http://quotesondesign.com/wp-json/posts') .pipe( map(response => response.data) ); } getQuote(id){ return this.http.get('http://quotesondesign.com/wp-json/posts/' + id) .pipe( map(response => response.data) ); } getRandomQuote(){ return this.http.get('http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1') .pipe( map(response => response.data) ); } }
The way in which we launch the request is much the same as the way we would do it with Angular, except that here we are explicitly mapping the response to only return the data. Although we don’t usually map responses in Angular, both map and pipe are just a part of the RxJS library and both are available to use in Angular – this isn’t a NestJS specific thing.
Using the Provider
With our provider created, we now need to make use of it inside of our Messages controller. We can do that by importing it and injecting it through the constructor.
Modify src/messages/messages.controller.ts to reflect the following:
import { Controller, Get, Param } from '@nestjs/common'; import { QuotesService } from '../services/quotes.service'; @Controller('messages') export class MessagesController { constructor(private quotesService: QuotesService){ } @Get() getMessages(){ return this.quotesService.getQuotes(); } @Get(':id') getMessage(@Param('id') id){ return this.quotesService.getQuote(id); } }
Our controller remains mostly the same as it was before, except now we are returning a call to the quotes service. We just return the observable returned by the HTTP request directly, and that will be handled by our Ionic application. Unlike in the last tutorial, now our route that accepts the id parameter is actually doing something useful, as it will return a specific quote from the API that matches that id.
Updating the Client
The last step is to utilise these changes in our front-end. We don’t really need to make any changes as we haven’t changed the structure of how our API works, but we will need to request an id that actually exists.
Modify src/app/home/home.page.ts to reflect the following:
import { Component, OnInit } from '@angular/core'; import { MessagesService } from '../services/messages.service'; @Component({ selector: 'app-home', templateUrl: 'home.page.html', styleUrls: ['home.page.scss'], }) export class HomePage implements OnInit { constructor(private messages: MessagesService){ } ngOnInit(){ this.messages.getMessages().subscribe((res) => { console.log(res); }); this.messages.getMessage('2463').subscribe((res) => { console.log(res); }); } }
If we were to serve this application now, we would see a response in the console that looks like this:
Summary
If you are already with Angular, then what we have covered will likely feel like pretty familiar territory. Although we could have easily launched those HTTP requests from within the controller itself, it is a good idea to use providers to handle the heavy lifting in the application – especially as the application starts to become more complex.
What to watch next...
VIDEO
via joshmorony – Learn Ionic & Build Mobile Apps with Web Tech https://ift.tt/2NI8oGc
0 notes
Quote
SAP TRAINING IN GHAZIABAD
https://helpingdotnet.blogspot.com/2015/05/httphandler-and-httpmodule-in-aspnet.html?showComment=1537258716158#c9147950844644266756 https://kishorecboracleapps.blogspot.com/2015/06/finding-nth-highest-salary-of-employee.html?showComment=1537258955830#c3936026734398698886 https://shahiddba.blogspot.com/2013/07/dba-interview-questions-with-answer.html?showComment=1537262675197#c7006415564622709966 https://www.blogger.com/comment.g?blogID=2202766463251903159&postID=217926372036189789&page=1&token=1537262792561 https://blogforce9.blogspot.com/2013/12/visualstrap-visualforce-implementation.html?showComment=1537262843677#c9146156719572291977 https://maximodev.blogspot.com/2016/05/industrial-internet-of-things-iot-iiot.html?showComment=1537262919555#c6451998894934695230 https://learningviacode.blogspot.com/2013/08/hibernate-cache-framework.html?showComment=1537262991157#c684650379632161679 https://salesforceworld.blogspot.com/2017/06/trailblazers-released-16-new-modules.html?showComment=1537263040180#c5922516465420179590 https://hadoopspark.blogspot.com/2017/03/89-spark-standalone-cluster.html?showComment=1537263077687#c1046111637606565988 https://tomstechnicalblog.blogspot.com/2016/10/kotlin-for-data-science.html?showComment=1537263161601#c6856075917574280303 https://wannabedatarockstar.blogspot.com/2016/12/automatically-parse-dates-in-any.html?showComment=1537263200450#c6352676962992826002 https://qualitythoughtchefpuppetdocker.blogspot.com/2017/03/chef-new-material-03302017.html?showComment=1537263377096#c7818257673238996237 https://pankajtiwarii.blogspot.com/2013/11/aspnet-interview-question-and-answer.html?showComment=1537263548155#c8000056799063066672 https://thevizioneer.blogspot.com/2014/03/tableau-30-for-30.html?showComment=1537263691242#c4503579383269436685 https://2k8618.blogspot.com/2009/04/inheritance-example-3-room-java.html?showComment=1537263742443#c8474889052936155920 https://seleniumworks.blogspot.com/2017/04/how-to-use-json-file-as-object.html?showComment=1537263843567#c8677172603158072085 https://manoharbabuapps.blogspot.com/2015/06/passing-multiple-values-for-single.html?showComment=1537263889185#c988777378334558761 https://appserptechnical.blogspot.com/2016/07/bulk-binds-bulk-collect-forall-and.html?showComment=1537263984561#c895947380780618228 http://www.bigdatabucket.com/2017/02/what-is-big-data-big-data-is-term-that.html?showComment=1537264122808#c2186818093371754093 https://thaneguide.blogspot.com/2013/08/php-training-institutes-in-thane-php.html?showComment=1537264199466#c2252227779454088309 https://usingaspdotnet.blogspot.com/2013/12/change-password-using-aspnet.html?showComment=1537264378502#c1465071566031972356 https://rohanwalia.blogspot.com/2016/06/create-oracle-cloud-database-connection.html?showComment=1537264490549#c5788015440108028103 https://www.blogger.com/comment.g?blogID=8472448211262689043&postID=7444750078614874106&page=1&token=1537264710862&isPopup=true https://corejavawithselenium.blogspot.com/2017/01/difference-between-collections-and.html?showComment=1537264904891#c8305281714306637966 https://www.blogger.com/comment.g?blogID=8214401912480503366&postID=1480101715182474385&page=1&token=1537264963234 https://www.blogger.com/comment.g?blogID=7083207935743500597&postID=2300639281265064712&page=1&token=1537265816022 https://training-centers.blogspot.com/2013/08/kalyan-it-training-institute-at-sr.html?showComment=1537266300143#c2359109464879575385 https://bhojarajusl.blogspot.com/2015/05/interview-questions-and-answers.html?showComment=1537266490505#c6746996781962295184 https://seleniumresource.blogspot.com/p/blog-page.html?showComment=1537266555993 https://csvls.blogspot.com/2010/10/video-lecture-of-core-java-and-advance.html?showComment=1537266762669#c7877290032807288595 https://angularjsinterviewquestionspdf.blogspot.com/2017/02/50-top-angularjs-interview-questions.html?showComment=1537266850921#c9175483725728167184 http://blog.opstree.com/2017/02/classless-inter-domain-routing-made-easy-cont.html?showComment=1537266917404#c7591151584132146297 https://crsktech.blogspot.com/2015/01/contact-us-crsktech-java-training.html?showComment=1537267104849#c3050115575179443845 https://noobtechiespeaks.blogspot.com/2014/11/smartwatch-part-1-real-time-clock.html?showComment=1537267162945#c1391785699451846082 https://maximodev.blogspot.com/2017/06/mxloader-attachments-doclinks.html?showComment=1537267205417#c1849342918365174436 https://www.blogger.com/comment.g?blogID=4454143640288911354&postID=8290723341318093762&page=2&token=1537268514164&isPopup=true https://qtp4free.blogspot.com/2010/04/what-are-goals-of-automation-testing.html?showComment=1537268627807#c7410248635846531852 https://scottsdigitalcommunity.blogspot.com/2013/11/developing-java-swing-application-that.html?showComment=1537268902820#c802303721312223097 https://phpdevelopmenttricks.blogspot.com/2017/03/php-interview-questions.html?showComment=1537269421810#c6343428325693219168 https://www.blogger.com/comment.g?blogID=6344606745263664972&postID=6301492023543575901&page=1&token=1537269503913 https://programming-digressions.blogspot.com/2015/08/best-spark-and-hadoop-books-in-god-we.html?showComment=1537269576020#c8001187737021573596 https://www.blogger.com/comment.g?blogID=2001595886969899899&postID=3035250837659633227&page=3&token=1537269732285 https://dinesh-malav.blogspot.com/2015/05/image-processing-using-opencv-on-hadoop.html?showComment=1537269839440#c1357651349684233501 https://aspnet-jitendra.blogspot.com/2013/07/aspnetmvcjquery-interview-questions-and.html?showComment=1537269946265#c5634306458920854361 https://automationtricks.blogspot.com/2015/02/what-is-implicit-explicit-fluent-wait.html?showComment=1537270042453#c6869599555324848510 https://sapficousa.blogspot.com/p/sap.html?showComment=1537270634538 https://chenchioracleebsappsr12.blogspot.com/p/blog-page_4.html?showComment=1537270734517 https://pkkjava.blogspot.com/p/angularjs-interview-questions.html?showComment=1537270776762 https://suhothayan.blogspot.com/2016/11/setting-up-hadoop-to-run-on-single-node_8.html?showComment=1537270984538#c4226590084585062749 https://amaralam.blogspot.com/2013/10/oracle-apps-technical-consultant.html?showComment=1537271014685#c8428277017351449708 https://php999.blogspot.com/2015/12/edit-incorrect-commit-message-in-git.html?showComment=1537271125432#c8544388679517352780 https://adavesh.blogspot.com/2012/06/interface-vs-abstract-class-why-and.html?showComment=1537271161289#c2882594611767465726 http://www.jamalyzeautorun.tk/2015/05/samsung-galaxy-s6-vs-iphone-6-ipi-bora.html?showComment=1537271189771#c4841277660383748729 https://codeobjectivec.blogspot.com/2016/07/get-user-data-from-facebook-in-ios.html?showComment=1537272197385#c8675200750961490007 https://maheshwaranm.blogspot.com/2013/05/hive-tutorial-part-2-internal-table-and.html?showComment=1537272337786#c2504774101177781641 https://androidmesh.blogspot.com/2016/11/sd-maid-pro-system-cleaning-tool-v440.html?showComment=1537272442391#c3526995525973284046 https://honeysalesforce.blogspot.com/2013/01/mnc-company-salesforce-interview.html?showComment=1537272475640#c4988442596925601271 https://oracleappssetup.blogspot.com/2014/02/oracle-scm-functional-interview.html?showComment=1537272513871#c1189844798557905928 https://www.blogger.com/comment.g?blogID=2062227964443456012&postID=3218978212285916335&page=1&token=1537272560733 https://www.blogger.com/comment.g?blogID=2062227964443456012&postID=3218978212285916335&page=1&token=1537272654129 https://atiinfos.blogspot.com/p/javanet-institutions.html?showComment=1537272705728 https://fieldecho.blogspot.com/2012/10/ios-6-do-not-disturb-mode.html?showComment=1537272748286#c4883237847685747642 https://www.blogger.com/comment.g?blogID=7531053927026721922&postID=3606409711324297034&page=1&token=1537272818787 https://www.blogger.com/comment.g?blogID=9842007&postID=7442244057197408035&page=1&token=1537272866910 https://sunilpatro1985.blogspot.com/2015/04/selenium-testing-for-angular-js-sites.html?showComment=1537273630296#c733983543370778950 https://yusinto.blogspot.com/2012/08/ios-6-auto-rotate-and-orientation.html?showComment=1537334697033#c6021416990489403041 https://transfer-iphone-6-data.blogspot.com/2015/11/transfer-data-contacts-from-iphone-to-iphone-7.html?showComment=1537334768644#c8865492964944743915 https://timvanosch.blogspot.com/2013/02/php-tutorial-making-webcrawler.html?showComment=1533382957310#c5879742290888010065 https://hundredminutehack.blogspot.com/2016/08/stepping-backwards-from-angularjs-to.html?showComment=1537334916661#c1212111288392340867 https://shadabashraf.blogspot.com/2010/12/cmc-ltd-training-cum-placement.html?showComment=1537335036883#c6852407443769796072 https://javadata.blogspot.com/2011/07/hibernate-and-enum-handling.html?showComment=1537335386580#c3675042318513097336 https://catchbug.blogspot.com/2013/09/java-abstract-class-vs-interfaces.html?showComment=1537335442631#c7791207446306727533 https://ios-recovery-software.blogspot.com/2015/11/fix-iphone6-white-screen-of-death.html?showComment=1537335581848#c2456327585288596251 https://seleniumsreekanth.blogspot.com/2017/01/1-what-is-selenium-faqs.html?showComment=1537335672119#c9162938976585740173 https://crackindotnet.blogspot.com/p/angularjs.html?showComment=1537335993607 https://tanmayblogspot.blogspot.com/2018/08/service-now-training-institutes-in-noida.html?showComment=1537336193362#c4856834514887083193 https://timvanosch.blogspot.com/2013/02/php-tutorial-making-webcrawler.html?showComment=1537336376533#c3073981733370868590 https://dotnetrealtimetasks.blogspot.com/2016/10/jquery-interview-questions-answers-1.html?showComment=1537336467404#c4690947810327599774 https://imobilecat.blogspot.com/2014/03/free-iphone-schematics-diagram-download.html?showComment=1537336586812#c1712806786339923660 https://itrainin.blogspot.com/2016/10/angularjs-training-in-chennai-angularjs.html?showComment=1537336689326#c9197260554193974759 https://bigcomputing.blogspot.com/2015/05/coursera-data-science-compared-to-data.html?showComment=1537336817256#c3928352504357866121 https://oracle-artifacts.blogspot.com/2012/04/collection-of-most-common-dba-interview.html?showComment=1537336854323#c6458968327446457588 https://dotnetdrives.blogspot.com/2011/11/log4net-database-logging_14.html?showComment=1537337006804#c1418507613953272577 https://www.blogger.com/comment.g?blogID=20066303&postID=2801310624427954087&page=1&token=1537337318825&isPopup=true https://venkatphp.blogspot.com/p/open-cart-tutorial.html?showComment=1537338980182 https://shanmugavelc.blogspot.com/2011/11/some-good-resourcesblogssites-for.html?showComment=1537339422741#c3194624280521599123 https://jq4you.blogspot.com/2013/04/jquery-attr-vs-prop-difference.html?showComment=1537339910559#c8609821248660545431 https://softtechhelp.blogspot.com/2013/07/angular-js-basic-terms.html?showComment=1537339949580#c5723056447784376162 https://mycodde.blogspot.com/2013/12/typeaheadjs-autocomplete-tutorial-ajax.html?showComment=1537340003531#c5377120961946546326 https://neweconomicseducation.blogspot.com/2012/02/learning-achievement.html?showComment=1537340128205#c8390530957120327206 https://codekeen.blogspot.com/2016/11/angularjs-interview-question-actual.html?showComment=1537340302478#c664862162678677569 https://stevefriend.blogspot.com/2013/05/angularjs-tutorial-and-net-web-api-part.html?showComment=1537340358668#c2534300690279189423 https://learningviacode.blogspot.com/2016/04/reverse-ajax-comet-technique.html?showComment=1537340390251#c2580150667831349975 https://internetofthings-pune.blogspot.com/2013/07/this-is-open-source-home-automation.html?showComment=1537340457815#c938656307787631193 https://funvision.blogspot.com/2016/01/internet-of-computer-vision-things.html?showComment=1537340517423#c6542897586668379769 https://abdennour-insat.blogspot.com/2013/05/jquery-template-clear-cache.html?showComment=1537340554118#c8576489382595370061 https://catchbug.blogspot.com/2014/08/selenium-selenium-webdriver-and.html?showComment=1537340591388#c2488195083140607707 https://javaj2eedevelopment.blogspot.com/2010/11/how-to-start-working-with-hibernate.html?showComment=1537340837679#c6452133659466351740 https://cool-php-tutorials.blogspot.com/2014/07/watupro-coupon-code.html?showComment=1537340992263#c8100656107899865725 https://sudhakarperformancetesting.blogspot.com/2011/07/performance-testing-tools.html?showComment=1537341373474#c2422120992283116385 https://netofeverything.blogspot.com/2017/06/split-mechanical-keyboard-by-coumbaya.html?showComment=1537341499815#c7390777997005761584 https://soulwithmobiletechnology.blogspot.com/2012/07/how-to-use-nsattributedstring-in-ios-6.html?showComment=1537341644842#c4475150979908841070 https://sivakumar4oracleappshome.blogspot.com/2012/09/functional-twitters-1.html?showComment=1537342312119#c2217679054526759697 https://oraclequizanswer.blogspot.com/2011/03/section-8.html?showComment=1537342366307#c5646541405706535549 https://interviewquestionjava.blogspot.com/2012/02/j2ee-servlet-servlet-life-cycle.html?showComment=1537342422313#c1978570418212691150 https://androidtutorialsrkt.blogspot.com/2017/01/listview-with-multiple-checkbox.html?showComment=1537342895799#c2059730968301658750 https://javawithswaranga.blogspot.com/2011/08/serialization-in-java.html?showComment=1537343301954#c6420382357596357382 https://dwhlaureate.blogspot.com/2012/08/joins-in-oracle.html?showComment=1537343337071#c3304895623955746424 https://www.blogger.com/comment.g?blogID=4385268314053126763&postID=1356853419854219352&page=1&token=1537343474162 https://www.blogger.com/comment.g?blogID=31809051&postID=115920506041395824&page=1&token=1537343664339 https://chennaijewellerydesignschool.blogspot.com/2015/03/chennai-jewellery-manufacturing.html?showComment=1537343721022#c8119537775587725252 https://oracleebspro.blogspot.com/2013/04/oracle-apps-interview-questions-3.html?showComment=1537343781717#c1851451276940814106 https://www.blogger.com/comment.g?blogID=6214248738198256800&postID=2588234963677377313&page=1&token=1537347691415 https://allinoneissues.blogspot.com/2013/07/hadoop-admin-interview-question-and.html?showComment=1537347732860#c8719683656325758579 https://trystans.blogspot.com/2011/08/roguelike-tutorial-01-java-eclipse.html?showComment=1537347819365#c2497984073040729564 https://salesforcepunk.blogspot.com/p/salesforce-topic-wise-interview.html?showComment=1537348101283 https://tutsforweb.blogspot.com/2012/05/auto-complete-text-box-with-php-jquery.html?showComment=1537348187814#c9170621016129961579 https://2k8618.blogspot.com/p/compiler-design-progams-lex-yacc.html?showComment=1537349677519 https://advancejavabyvinay.blogspot.com/2015/04/advance-java-concepts-easy-way.html?showComment=1537351434493#c7520769577579089610 https://advancejavabyvinay.blogspot.com/2015/04/advance-java-concepts-easy-way.html?showComment=1537351434493#c7520769577579089610 https://techsahre.blogspot.com/2011/01/ruby-and-salesforce-integration-with.html?showComment=1537351721398#c5660185016751774159 https://vadimdev.blogspot.com/2014/08/angularjs-custom-scrollbar-directive.html?showComment=1537351883759#c392235484372787004 https://dotnetprojectsourcecode.blogspot.com/2015/08/sql-server-tricks.html?showComment=1537351955561#c1076577911185396756 https://selenium-venkat.blogspot.com/p/01_41.html?showComment=1537352035462 https://www.blogger.com/comment.g?blogID=248726242367252546&postID=6692430504833893602&page=1&token=1537352475173 https://cloudn1n3.blogspot.com/2014/11/from-devops-to-puppet-part-2.html?showComment=1537352581026#c1281352211233325943 https://www.blogger.com/comment.g?blogID=4989387369016152901&postID=6090260717118941801&page=1&token=1537353619795 https://ilmuwebsite99.blogspot.com/2012/03/script-code-php-auto-post-blogspot.html?showComment=1537354060845#c2803828813301059886 https://mvvmcross.blogspot.com/2013/12/n0-first-mvvmcross-application-blog.html?showComment=1537354888816#c3214166628432553406 https://mydevbits.blogspot.com/2016/08/automating-creation-of-chatbot-dialog.html?showComment=1537355302238#c4087737936482591663 https://phpcodeforlearner.blogspot.com/2012/07/php-login-page-with-md5-possword.html?showComment=1537355407904#c5996665623349196225 https://www.blogger.com/comment.g?blogID=6107510225675862978&postID=796622177824675454&page=1&token=1537355475669&isPopup=true https://www.blogger.com/comment.g?blogID=8925876803861725458&postID=3394741460577379227&page=1&token=1537355723090 https://techloverforum.blogspot.com/2014/02/51-oracle-sql-plsql-interview-questions.html?showComment=1537355922731#c5025710456348945486 https://dbaregistry.blogspot.com/2010/02/oracle-rac-interview-questions.html?showComment=1537356240939#c7394125700168746416 https://www.blogger.com/comment.g?blogID=7966719247111983224&postID=5487476340535637764&page=1&token=1537356290729&isPopup=true https://bharatoracleappstechnical.blogspot.com/2012/09/good-blog-link-for-fusion.html?showComment=1537356586913#c4562282806312973843 https://www.blogger.com/comment.g?blogID=35849895&postID=5219067505395629300&page=1&token=1537356622801 https://www.blogger.com/comment.g?blogID=25295105&postID=7649119723347205826&page=1&token=1537357015909 https://java-easy-tutorial.blogspot.com/2012/06/core-java-tips-and-tricks.html?showComment=1537357049679#c1750396632965197903 https://jitu1990.blogspot.com/2015/05/share-with-facebook-from-ios-app.html?showComment=1537357086977#c3712622301502359342 https://www.blogger.com/comment.g?blogID=19760223&postID=5325971652339043956&page=1&token=1537357147474 https://maximodev.blogspot.com/2016/06/watson-iot-mqtt-apis-walkthrough-tutorial.html?showComment=1537357182186#c813253207557755475 https://iffycan.blogspot.com/2013/07/angular-injection.html?showComment=1537357212368#c1650890373198255181 https://tonyisageek.blogspot.com/2014/07/angularjs-and-worklight-mobile.html?showComment=1537357240501#c3964724724977485325 https://pcusefultricks12.blogspot.com/2016/04/traffic-rider-ios-game-hack-cheat-no.html?showComment=1537357287990#c9130892435561558994 https://enjoytableau.blogspot.com/2014/07/how-to-show-multiple-marks-in-worksheet.html?showComment=1537357387209#c1684276084912767531 https://tableaublogspot.blogspot.com/2015/02/tableau-inter-view-questions.html?showComment=1537357420014#c2048454072506114650 https://askforhadoop.blogspot.com/2013/09/how-to-write-mapreduce-program-in-java.html?showComment=1537357444372#c381163705221614034 https://selenium-breakthrough.blogspot.com/2017/01/working-with-dropdowns-with-selenium.html?showComment=1537357654263#c8464718896359380097 https://www.blogger.com/comment.g?blogID=4535123449935735221&postID=216587268260253335&page=1&token=1537357760251 https://exploresalesforce.blogspot.com/2012/01/how-to-clear-dev-501-exam.html?showComment=1537357796723#c6586470818097146317 https://tableautraininginstitutesbangalore.blogspot.com/2014/11/tableau-training-institutes-bangalore.html?showComment=1537357828733#c1654494971193928931 https://hadoop-tutorial.blogspot.com/2015/06/future-of-big-data-hadoop.html?showComment=1537358650266#c8987266992857431969 https://webtrackkerinstitute.blogspot.com/2017/04/java-training-institute-in-ghaziabad.html?showComment=1537358681634#c3173962595459174362 https://uamarshaikh.blogspot.com/2014/02/cloud-computing-aws-online-training-us.html?showComment=1537358708016#c2286950716820004634 https://iphonebyradix.blogspot.com/2013/12/phonegap-introduction.html?showComment=1537358735603#c3709243976493966070 https://stjohnambulance77.blogspot.com/2011/06/ambattur.html?showComment=1537358761478#c2332523818018187388 https://comptechnocrat.blogspot.com/2011/04/latest-tools-and-frameworks-for-php.html?showComment=1537358791191#c8620476675493280315 https://www.blogger.com/comment.g?blogID=21310324&postID=7925197860673170380&page=1&token=1537358839247
0 notes
Text
Implement Custom HttpHandler And Custom HttpModule
This blog explains the role of HTTPHandler and HTTPModule in ASP.NET applications. We will try to work on a basic example to see how these can be implemented and how we can create our own custom HttpHandler and HTTP Module from C-Sharpcorner Latest Content https://ift.tt/2lQ2J0i
0 notes
Text
Dot Net Core Interview Questions and Answers - Part 10:
Q094. What is Middleware in ASP.NET Core? How it is different from HttpHandlers and HttpModules of classic ASP.Net? Q095. What is the use of the Middleware in the ASP.Net Core App? Q096. Where the Middlewares are registered in the .Net Core Application? Q097. What is the order of Middlewares in the .Net Core App? Why ExceptionHandler middleware is placed very first in ASP.NET Core? Q098. How can you configure the Middleware Component in ASP.Net Core? What is the use of Configure() method? Q099. What is Request Delegate in .Net Core? Q100. What is the difference between app.Use() and app.Run() methods in .Net Core? Q101. How to Configure Middleware Components using the Use() extension method? Q102. How to Configure Middleware Components using the Run() extension method? Q103. What is the use of next.Invoke() method in .Net Core? What are the limitations of using this?
#dotnetcoreinterviewquestions#aspdotnetcore#coreinterviewquestionsandanswers#CSharpInterviewQuestionsAndAnswers#dotnetInterview#InterviewPreparation#InterviewQuestionsAndAnswers#techpointfundamentals#techpointfunda#techpoint
1 note
·
View note
Text
Getting started with ASP.NET MVC
In this article, we are going to create a really simple application using ASP.NET MVC to get more familiar with this technology.
Introduction
Through this post, we are going to build a really simple application using the ASP.NET MVC technology. It is going to be pretty straightforward and this will allow us to have a brief overview of this tool.
What is ASP.NET MVC?
ASP.NET MVC is an open-source software created by Microsoft. In a few words, it is some kind of web development framework based on ASP.NET. As its name tells us, it is an MVC framework and this last one allows us to create dynamic web applications.
Recently, Microsoft released ASP.NET Core. This last one also allows us to develop applications using the MVC pattern, but has a slightly different approach. The main differences are that ASP.NET Core is open source and cross-platform. But we are not going to focus on this one here.
What is MVC?
Firstly, let's refresh our mind and let's have a look at MVC. MVC, or Model-View-Controller, is a pattern that allows us to separate an application in three main components: Model, View, Controller. Now, we can debate over the question, "is MVC a design pattern or an architectural pattern?" but that's another subject. Here, we have to retain the following information:
Model
The Model represents the data business logic layer. The Business Logic should be encapsulated in the model, along with any implementation logic for persisting the state of the application.
View
Views are responsible for presenting content through the user interface. There should be minimal logic within a View and this logic should be related to presenting content.
Controller
A Controller is a component that handles and responds to user input and interaction. It renders the appropriate View with the Model data as a response. So, it is responsible for selecting which Model type to work with and which View to render.
Creating our project
Let's head to Visual Studio and choose "New Project > Visual C# > Web > ASP.NET We Application (.NET Framework)". After we entered a name for our application, we can go to the next step and chose the "MVC" option. We can check the box for unit tests if we want to generate a second assembly for unit testing.
Project structure
Now that our application is generated, let's take a look at the different folders we have.
Application information
Properties - application properties (application type, startup object, assembly information)
References - used to pull additional libraries into the project
Application folders
App_Data - application data (for example, SQL database)
Content - static files like CSS files, icons or images
Controllers - Controller classes
Fonts - custom font files
Models - Model classes
Scripts - JavaScript files
Views - HTML files for views
Configuration files
Global.asax - contains code for responding to application-level events raised by ASP.NET or by HttpModules
packages.config - is managed by the NuGet infrastructure and tracks installed packages with their respective versions
Web.config - contains settings that apply to the web site
First run
Now, let's hit "F5", or click the "play" button in Visual Studio and wait a few seconds. This will start IIS Express and run our web app. Visual Studio then launches a browser and opens the application's home page. If everything is alright, our application will by available at "localhost:RANDOMPORT_".
Creating a Controller, a Model and a View
It is now time to create our first Controller. To achieve this, in the Solution Explorer, we need to right-click on the Controllers folders and choose "Add > Controller". Select "MVC 5 Controller - Empty" and name our Controller "GamesController". As we can see, the Controller was created in the "Controllers" folder, but a new folder, named "Games" was also generated in the "Views" folder. Now, let's create a Model by right-clicking on the Models folder and choosing "Add > Class". Let's call this Model "Game". Let's give our Model a few properties.
public class Game { public int Id { get; set; } public string Name { get; set; } }
Models/Game.cs file
Now let's create a View. For this, we need to right-click on the "Views/Games" folder and select "Add > View". Let's name this view "Index" and, under the "Layout" option, select the layout named "_Layout.cshtml" in "Views/Shared".
Let's go back to our "GamesController" and fill it like so:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using WebApplication1.Models; namespace WebApplication1.Controllers { public class GamesController : Controller { // GET: Games public ActionResult Index() { Game game = new Game() { Name = "Super Mario Bros" }; return View(game); } } }
Controllers/GamesController.cs file
Here, we just have one action, "Index()", where we create a new "Game" object before passing it to the specific View. the "View()" method is inherited from the base Controller class. It returns a "ViewResult" object that is derived from "ActionResult".
In our recently created View, let's put the following code:
model WebApplication1.Models.Game @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>@Model.Name</h2>
Views/Games/Index.cshtml file
At the top of the file, we can see a few properties. The "@model" at the very top defines the type of the Model used with this View. "ViewBag.Title" is basically the title of the page showed in the browser. "Layout" is the layout for this view. In the body of the View, we can see something like "@Model". Every View has this property which gives us access to the Model we pass to it in the Controller.
Now, if we go to "localhost:RANDOMPORT/games_", we should have something interesting.
Creating Routes & Action Parameters
Now it is time to confront ourselves with Routes and Action Parameters.
When a request comes into our application, the ASP.NET MVC Framework maps request data to parameters values for Action Methods. If an Action Method takes a parameter, the framework looks for a parameter with the exact same name in the request data. If the parameter exists, it will be passed to the Action.
Let's define a new Action in our "GamesController":
public ActionResult Edit(int id, string stringParameter, int? optionalParameter) { if (String.IsNullOrWhiteSpace(stringParameter)) { stringParameter = "None"; } if (!optionalParameter.HasValue) { optionalParameter = 1; } return Content(String.Format("id={0}&stringParameter={1}&optionParameter={2}", id, stringParameter, optionalParameter)); }
Controllers/GamesController.cs file edited
Here, we add three parameters to our Action. The first is and ID, the second a string and the third an optional integer. Now if we go to "localhost:RANDOMPORT/games/edit?id=1&stringParameter=someString&optionalParameter=42_", we should have something on the screen. Here, we just use the query string to pass our parameters. But we can do something more elegant by defining some Routes.
Routes are available in the "AppStart/RouteConfig.cs" file. As we can see, there is a default _Route that works for most scenarios. However, let's define a custom Route. Let's place the following code before the default Route.
routes.MapRoute( name: "EditGame", url: "games/edit/{id}/{stringParameter}/{optionalParameter}", defaults: new { controller = "Games", action = "Edit" } );
Defining a custom Route in AppStart/RouteConfig.cs_
If we go to "localhost:RANDOMPORT/games/edit/1/foo/42_", we should see something.
This way to create Routes is not really clean if we have many custom Routes. So, let's delete this code and replace it with this one:
routes.MapMvcAttributeRoutes();
Adding Attributes Routes in AppStart/RouteConfig.cs_
Now, go back to our "GamesController" to edit it like so:
[Route("games/edit/{id}/{stringParameter}/{optionalParameter:regex(\\d{2})}")] public ActionResult Edit(int id, string stringParameter, int? optionalParameter) { ... }
Controllers/GamesController.cs file edited
Here, we just place our URL pattern in an attribute before our "Edit()" action. Notice that we also, on this occasion, add a constraint to the third parameter.
View Models
For now, we just display the name of a game in our view "Index". What if we want to display more information? To achieve this, we can use a View Model. A View Model is a Model build for a View, including data and rules specific to that View.
Let's say we want to display characters that are in our game. To achieve this, let's create a new Model name "Character".
public class Character { public int Id { get; set; } public string Name { get; set; } }
Models/Character.cs file
Now, let's create a folder named "ViewModels" at the root of our project. We can now place a new class in this folder. Name this last one "IndexGameViewModel". We can fill it like so:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using WebApplication1.Models; namespace WebApplication1.ViewModels { public class IndexGameViewModel { public Game Game { get; set; } public List<Character> Characters { get; set; } } }
ViewModels/IndexGameViewModel.cs file
Now, go back to our "GamesController" and edit it like so:
using System.Web; using System.Web.Mvc; using WebApplication1.Models; using WebApplication1.ViewModels; namespace WebApplication1.Controllers { public class GamesController : Controller { // GET: Games public ActionResult Index() { Game game = new Game() { Name = "Super Mario Bros" }; List<Character> characters = new List<Character> { new Character { Name = "Mario" }, new Character { Name = "Luigi" }, new Character { Name = "Peach" }, new Character { Name = "Bowser" } }; IndexGameViewModel viewModel = new IndexGameViewModel() { Game = game, Characters = characters }; return View(viewModel); } ... } }
Controllers/GamesController.cs file edited
As we can see, we added a few lines in our "Index()" action. We created a "List" containing a list of characters and a "IndexGameViewModel" object that we pass to the View.
We also have to edit our View like so:
@using WebApplication1.Models; @model WebApplication1.ViewModels.IndexGameViewModel @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>@Model.Game.Name</h2> <ul> @foreach (Character character in Model.Characters) { <li>@character.Name</li> } </ul>
Views/Games/Index.cshtml file edited
We can go back to "localhost:RANDOMPORT/games_" to see the result.
Using Entity Framework
Let's go a little further and use the Entity Framework. Entity Framework is an object-relational mapper (ORM) that allows us to work with a database using .NET objects. It supports a development paradigm called Code First. It lets us create Model objects by writing simple classes (also known as POCO classes, from "plain-old CLR objects"). We can have the database created on the fly from our classes.
First, we need to install the Entity Framework. We can achieve this by calling the graphic Package Manager or using the command line version like so:
PM> Install-Package EntityFramework -Version 6.2.0
Installing Entity Framework
Now, let's create another Model named "Enemy" and fill it like so:
using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Web; namespace WebApplication1.Models { public class Enemy { public int Id { get; set; } public string Name { get; set; } } }
Models/Enemy.cs file
Now, we can create a new folder, at the root of our project, named "DAL" (Data Access Layer). We now need to create a "Context". It is the class that coordinates Entity Framework functionality for a given data model.
using System; using System.Data.Entity; using System.Data.Entity.ModelConfiguration.Conventions; using WebApplication1.Models; namespace WebApplication1.DAL { public class GameContext : DbContext { public GameContext() : base("GameContext") { } public DbSet<Enemy> Enemies { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); } } }
DAL/GameContext.cs file
First, we pass the name of the connection string to the constructor.
Then, and because it is just a really simple example, we create only one "DbSet" property. A "DbSet" corresponds to a database table and an entity corresponds to a row in the table.
Finally, we specify we don't want our tables in the database to be pluralized.
We can now initialize the database with test data. So, in the "DAL" folder, we can create a file named "GameInitializer".
using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Web; using WebApplication1.Models; namespace WebApplication1.DAL { public class GameInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<GameContext> { protected override void Seed(GameContext context) { var enemies = new List<Enemy> { new Enemy{Name="Goomba"}, new Enemy{Name="Koopa Troopa"}, new Enemy{Name="Lakitu"}, new Enemy{Name="Boo"} }; enemies.ForEach(e => context.Enemies.Add(e)); context.SaveChanges(); } } }
DAL/GameInitializer.cs file
Here, we initialize the database with test data. We specify that we want to drop the database each time the model changes. This is great for development, but obviously, we don't want it in production.
The "Seed()" method takes the database context object as an input parameter, and the code in the method uses that object to add new entities to the database.
We now have to edit the "Web.config" file to use our initializer.
<entityFramework> <contexts> <context type="WebApplication1.DAL.GameContext, WebApplication1"> <databaseInitializer type="WebApplication1.DAL.GameInitializer, WebApplication1" /> </context> </contexts> ... </entityFramework>
Web.config file edited
Setting up Entity Framework to use LocalDB
LocalDB is a lightweight version of the SQL Server Express Database Engine. LocalDB runs in a special execution mode of SQL Server Express that allows us to work with databases as ".mdf" files. LocalDB is installed by default with Visual Studio.
Let's edit again our "Web.config" file:
<connectionStrings> <add name="GameContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=WebApplication1;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/> </connectionStrings> <appSettings> ... </appSettings>
Web.config file edited
Another Controller
We are now going to create another Controller name "EnemyController" using the "MVC 5 Controller with views, using Entity Framework" option. We can enter "Enemy" as the Model class and "GameContext" for the database context. After a few seconds, we can see that a Controller with some code in it and a bunch of Views have been created for us.
It is time to run our application again. Let's go to "localhost:RANDOMPORT/enemy_" to see the result. As we can see by looking at the result and the code, a lot has been made for us.
Migrations
In a real application, our data model will change frequently. So, for each change, we need to sync that database. For now, we have configured the Entity Framework to automatically drop and re-create the database each time we change the data model. This is alright for development, but not for production because we would lose data. To solve this problem, we need to enable the Code First Migrations feature.
First, we need to edit the "Web.config" file:
... <connectionStrings> <add name="GameContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=WebApplication12;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/> </connectionStrings> ... <!-- remove or comment <contexts> <context type="WebApplication1.DAL.GameContext, WebApplication1"> <databaseInitializer type="WebApplication1.DAL.GameInitializer, WebApplication1" /> </context> </contexts> -->
Web.config file edited
It isn't required to change the database as we did here, but that will let the first migration create a new database.
We can now enable migrations:
PM> enable-migrations PM> add-migration InitialCreate
Enabling migrations and adding a migration
As we can see, a "Migrations" folder has been created. In this folder, we can find a file "Configuration" that contains a "Seed()" method like our initializer. Let's place the following code into that file:
protected override void Seed(WebApplication1.DAL.GameContext context) { var enemies = new List<Enemy> { new Enemy{Name="Goomba"}, new Enemy{Name="Koopa Troopa"}, new Enemy{Name="Lakitu"}, new Enemy{Name="Boo"} }; enemies.ForEach(e => context.Enemies.AddOrUpdate(p => p.Name, e)); context.SaveChanges(); }
Migrations/Configuration.cs file
In the "Migrations" folder, we can also find the code that would create the database from scratch. The "Up()" method creates the database tables that correspond to the data model entity sets, and the "Down()" method deletes them.
Now, edit our "Enemy" Model like so:
public class Enemy { public int Id { get; set; } public string Name { get; set; } public int Level { get; set; } }
Models/Enemy.cs file edited
Then, change the "Configuration" file:
protected override void Seed(WebApplication1.DAL.GameContext context) { var enemies = new List<Enemy> { new Enemy{Name="Goomba", Level=1}, new Enemy{Name="Koopa Troopa", Level=2}, new Enemy{Name="Lakitu", Level=5}, new Enemy{Name="Boo", Level=4} }; enemies.ForEach(e => context.Enemies.AddOrUpdate(p => p.Name, e)); context.SaveChanges(); }
Migrations/Configuration.cs file edited
We can now create a migration and execute it:
PM> add-migration EnemyModelEdited PM> update-database -TargetMigration EnemyModelEdited
Creating and executing a migration
We can use the Server Explorer to see that our migration has been run.
Unit Testing
Let's talk a little bit about unit tests. If we checked the appropriate box when we created the project, we should see, in the Solution Explorer, a second Assembly made for unit tests. If it isn't the case, we have to add a new project to our solution (right-click on our solution, "Add > Project") using the unit test template. After that, we had to create a reference to our first project in the second project (right-click on "References", "Add reference"). We also need to add a few other things like "System.Web" in reference. We then need to install the "Microsoft AspNet Mvc" package. This will probably require from us to update the package in the first project.
Keep things very simple and in the file "UnitTest1.cs", put the following code:
using System; using System.Web; using System.Web.Mvc; using Microsoft.VisualStudio.TestTools.UnitTesting; using WebApplication1; using WebApplication1.Controllers; namespace WebApplication1Test { [TestClass] public class GameControllerTest { [TestMethod] public void Index() { GamesController controller = new GamesController(); ViewResult result = controller.Index() as ViewResult; Assert.IsNotNull(result); } } }
UnitTest1.cs file
We can now execute our test and if everything is alright, we should have a success message.
Conclusion
Through this article, we got an overview of the ASP.NET MVC Framework. We saw the basic concepts it uses. We built a small application using the MVC pattern and saw the different options that we have to create a dynamic web application. We saw how to create basic Models, Views and Controllers. We had a brief overview of the Entity Framework and how to use it. We are now ready to get further, because, of course, here, we didn't talk about production environment or the Repository Pattern.
One last word
If you like this article, you can consider supporting and helping me on Patreon! It would be awesome! Otherwise, you can find my other posts on Medium and Tumblr. You will also know more about myself on my personal website. Until next time, happy headache!
0 notes
Link
SitePoint http://j.mp/2yeXEpl
This article was originally published on OKTA Developer Blog. Thank you for supporting the partners who make SitePoint possible.
Angular (formerly called Angular 2.0) is quickly becoming one of the most powerful ways to build a modern single-page app. A core strength is Angular’s focus on building reusable components, which help you decouple the various concerns in your application. Take authentication, for example: it can be painful to build, but once you wrap it in a component, the authentication logic can be reused throughout your application.
The Angular CLI makes it easy to scaffold new components, and even entire projects. If you haven’t used the Angular CLI to quickly generate Angular code, you’re in for a treat!
In this example, you’ll build a simple web application with Angular CLI, a tool for Angular development. You’ll create an application with search and edit features, then add authentication.
Create an Angular Application
TIP: If you’d like to skip building the Angular application and get right to adding authentication, you can clone my ng-demo project, then skip to the Create an OpenID Connect App in Okta section.
git clone http://j.mp/2xxKArx
What You’ll Need
About 20 minutes
A favorite text editor or IDE. I recommend IntelliJ IDEA
Node.js and npm installed. I recommend using nvm
Angular CLI installed. If you don’t have Angular CLI installed, install it using npm install -g @angular/cli
Create a new project using the ng new command:
ng new ng-demo
This will create a ng-demo project and run npm install in it. It should take about a minute to complete, but that could vary depending on your connection speed.
[mraible:~/dev] $ ng new ng-demo installing ng create .editorconfig create README.md create src/app/app.component.css create src/app/app.component.html create src/app/app.component.spec.ts create src/app/app.component.ts create src/app/app.module.ts create src/assets/.gitkeep create src/environments/environment.prod.ts create src/environments/environment.ts create src/favicon.ico create src/index.html create src/main.ts create src/polyfills.ts create src/styles.css create src/test.ts create src/tsconfig.app.json create src/tsconfig.spec.json create src/typings.d.ts create .angular-cli.json create e2e/app.e2e-spec.ts create e2e/app.po.ts create e2e/tsconfig.e2e.json create .gitignore create karma.conf.js create package.json create protractor.conf.js create tsconfig.json create tslint.json Successfully initialized git. Installing packages for tooling via npm. Installed packages for tooling via npm. You can `ng set --global packageManager=yarn`. Project 'ng-demo' successfully created. [mraible:~] 46s $
You can see the what version of Angular CLI you’re using with ng --version.
$ ng --version _ _ ____ _ ___ / \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _| / △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | | / ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | | /_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___| |___/ @angular/cli: 1.3.2 node: 8.4.0 os: darwin x64
Run Your Angular Application
The project is configured with webpack dev server. To start it, make sure you’re in the ng-demo directory, then run:
ng serve
You should see a screen like the one below at http://localhost:4200.
You can make sure your new project’s tests pass, run ng test:
$ ng test ... Chrome 60.0.3112 (Mac OS X 10.12.6): Executed 3 of 3 SUCCESS (0.239 secs / 0.213 secs)
Add a Search Feature
To add a search feature, open the project in an IDE or your favorite text editor. For IntelliJ IDEA, use File > New Project > Static Web and point to the ng-demo directory.
In a terminal window, cd into your project’s directory and run the following command. This will create a search component.
$ ng g component search installing component create src/app/search/search.component.css create src/app/search/search.component.html create src/app/search/search.component.spec.ts create src/app/search/search.component.ts update src/app/app.module.ts
Open src/app/search/search.component.html and replace its default HTML with the following:
<h2>Search</h2> <form> <input type="search" name="query" [(ngModel)]="query" (keyup.enter)="search()"> <button type="button" (click)="search()">Search</button> </form> <pre></pre>
The Router documentation for Angular provides the information you need to setup a route to the SearchComponent you just generated. Here’s a quick summary:
In src/app/app.module.ts, add an appRoutes constant and import it in @NgModule:
import { Routes, RouterModule } from '@angular/router'; const appRoutes: Routes = [ {path: 'search', component: SearchComponent}, {path: '', redirectTo: '/search', pathMatch: 'full'} ]; @NgModule({ ... imports: [ ... RouterModule.forRoot(appRoutes) ] ... }) export class AppModule { }
In src/app/app.component.html, adjust the placeholder content and add a <router-outlet> tag to display routes.
<h1>Welcome to !</h1> <!-- Routed views go here --> <router-outlet></router-outlet>
Now that you have routing setup, you can continue writing the search feature.
If you still have ng serve running, your browser should refresh automatically. If not, navigate to http://localhost:4200. You will likely see a blank screen. Open your JavaScript console and you’ll see the problem.
To solve this, open src/app/app.module.ts and add FormsModule as an import in @NgModule:
import { FormsModule } from '@angular/forms'; @NgModule({ ... imports: [ ... FormsModule ] ... }) export class AppModule { }
Now you should see the search form.
If you want to add CSS for this components, open src/app/search/search.component.css and add some CSS. For example:
:host { display: block; padding: 0 20px; }
This section has shown you how to generate a new component to a basic Angular application with Angular CLI. The next section will show you how to create and use a JSON file and localStorage to create a fake API.
To get search results, create a SearchService that makes HTTP requests to a JSON file. Start by generating a new service.
$ ng g service search installing service create src/app/search.service.spec.ts create src/app/search.service.ts WARNING Service is generated but not provided, it must be provided to be used
Move the generated search.service.ts and its test to app/shared/search. You’ll need to create this directory.
mkdir -p src/app/shared/search mv src/app/search.service.* src/app/shared/search/.
Create src/assets/data/people.json to hold your data.
[ { "id": 1, "name": "Peyton Manning", "phone": "(303) 567-8910", "address": { "street": "1234 Main Street", "city": "Greenwood Village", "state": "CO", "zip": "80111" } }, { "id": 2, "name": "Demaryius Thomas", "phone": "(720) 213-9876", "address": { "street": "5555 Marion Street", "city": "Denver", "state": "CO", "zip": "80202" } }, { "id": 3, "name": "Von Miller", "phone": "(917) 323-2333", "address": { "street": "14 Mountain Way", "city": "Vail", "state": "CO", "zip": "81657" } } ]
Modify src/app/shared/search/search.service.ts and provide Http as a dependency in its constructor. In this same file, create a getAll() method to gather all the people. Also, define the Address and Person classes that JSON will be marshalled to.
import { Injectable } from '@angular/core'; import { Http, Response } from '@angular/http'; import 'rxjs/add/operator/map'; @Injectable() export class SearchService { constructor(private http: Http) {} getAll() { return this.http.get('assets/data/people.json') .map((res: Response) => res.json()); } } export class Address { street: string; city: string; state: string; zip: string; constructor(obj?: any) { this.street = obj && obj.street || null; this.city = obj && obj.city || null; this.state = obj && obj.state || null; this.zip = obj && obj.zip || null; } } export class Person { id: number; name: string; phone: string; address: Address; constructor(obj?: any) { this.id = obj && Number(obj.id) || null; this.name = obj && obj.name || null; this.phone = obj && obj.phone || null; this.address = obj && obj.address || null; } }
To make these classes available for consumption by your components, edit src/app/shared/index.ts and add the following:
export * from './search/search.service';
The reason for creating this file is so you can import multiple classes on a single line rather than having to import each individual class on separate lines.
In src/app/search/search.component.ts, add imports for these classes.
import { Person, SearchService } from '../shared';
You can now add query and searchResults variables. While you’re there, modify the constructor to inject the SearchService.
export class SearchComponent implements OnInit { query: string; searchResults: Array<Person>; constructor(private searchService: SearchService) {}
Then implement a search() method to call the service’s getAll() method.
search(): void { this.searchService.getAll().subscribe( data => { this.searchResults = data; }, error => console.log(error) ); }
At this point, you’ll likely see the following message in your browser’s console.
ORIGINAL EXCEPTION: No provider for SearchService!
To fix the “No provider” error from above, update app.module.ts to import the SearchService and add the service to the list of providers. Because SearchService depends on Http, you’ll need to import HttpModule as well.
import { SearchService } from './shared'; import { HttpModule } from '@angular/http'; @NgModule({ ... imports: [ ... HttpModule ], providers: [SearchService], bootstrap: [AppComponent] })
Now clicking the search button should work. To make the results look better, remove the <pre> tag and replace it with a <table> in src/app/search/search.component.html.
<table *ngIf="searchResults"> <thead> <tr> <th>Name</th> <th>Phone</th> <th>Address</th> </tr> </thead> <tbody> <tr *ngFor="let person of searchResults; let i=index"> <td></td> <td></td> <td><br/> , </td> </tr> </tbody> </table>
Then add some additional CSS in src/app/search/search.component.css to improve its table layout.
table { margin-top: 10px; border-collapse: collapse; } th { text-align: left; border-bottom: 2px solid #ddd; padding: 8px; } td { border-top: 1px solid #ddd; padding: 8px; }
Now the search results look better.
But wait, you still don’t have search functionality! To add a search feature, add a search() method to SearchService.
import { Observable } from 'rxjs'; search(q: string): Observable<any> { if (!q || q === '*') { q = ''; } else { q = q.toLowerCase(); } return this.getAll().map(data => data.filter(item => JSON.stringify(item).toLowerCase().includes(q))); }
Then refactor SearchComponent to call this method with its query variable.
search(): void { this.searchService.search(this.query).subscribe( data => { this.searchResults = data; }, error => console.log(error) ); }
Now search results will be filtered by the query value you type in.
This section showed you how to fetch and display search results. The next section builds on this and shows how to edit and save a record.
Add an Edit Feature
Modify src/app/search/search.component.html to add a link for editing a person.
<td><a [routerLink]="['/edit', person.id]"></a></td>
Run the following command to generate an EditComponent.
$ ng g component edit installing component create src/app/edit/edit.component.css create src/app/edit/edit.component.html create src/app/edit/edit.component.spec.ts create src/app/edit/edit.component.ts update src/app/app.module.ts
Add a route for this component in src/app/app.module.ts:
const appRoutes: Routes = [ {path: 'search', component: SearchComponent}, {path: 'edit/:id', component: EditComponent}, {path: '', redirectTo: '/search', pathMatch: 'full'} ];
Update src/app/edit/edit.component.html to display an editable form. You might notice I’ve added id attributes to most elements. This is to make things easier when writing integration tests with Protractor.
<div *ngIf="person"> <h3></h3> <div> <label>Id:</label> </div> <div> <label>Name:</label> <input [(ngModel)]="editName" name="name" id="name" placeholder="name"/> </div> <div> <label>Phone:</label> <input [(ngModel)]="editPhone" name="phone" id="phone" placeholder="Phone"/> </div> <fieldset> <legend>Address:</legend> <address> <input [(ngModel)]="editAddress.street" id="street"><br/> <input [(ngModel)]="editAddress.city" id="city">, <input [(ngModel)]="editAddress.state" id="state" size="2"> <input [(ngModel)]="editAddress.zip" id="zip" size="5"> </address> </fieldset> <button (click)="save()" id="save">Save</button> <button (click)="cancel()" id="cancel">Cancel</button> </div>
Modify EditComponent to import model and service classes and to use the SearchService to get data.
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Address, Person, SearchService } from '../shared'; import { Subscription } from 'rxjs'; import { ActivatedRoute, Router } from '@angular/router'; @Component({ selector: 'app-edit', templateUrl: './edit.component.html', styleUrls: ['./edit.component.css'] }) export class EditComponent implements OnInit, OnDestroy { person: Person; editName: string; editPhone: string; editAddress: Address; sub: Subscription; constructor(private route: ActivatedRoute, private router: Router, private service: SearchService) { } ngOnInit() { this.sub = this.route.params.subscribe(params => { const id = + params['id']; // (+) converts string 'id' to a number this.service.get(id).subscribe(person => { if (person) { this.editName = person.name; this.editPhone = person.phone; this.editAddress = person.address; this.person = person; } else { this.gotoList(); } }); }); } ngOnDestroy() { this.sub.unsubscribe(); } cancel() { this.router.navigate(['/search']); } save() { this.person.name = this.editName; this.person.phone = this.editPhone; this.person.address = this.editAddress; this.service.save(this.person); this.gotoList(); } gotoList() { if (this.person) { this.router.navigate(['/search', {term: this.person.name} ]); } else { this.router.navigate(['/search']); } } }
Modify SearchService to contain functions for finding a person by their id, and saving them. While you’re in there, modify the search() method to be aware of updated objects in localStorage.
search(q: string): Observable<any> { if (!q || q === '*') { q = ''; } else { q = q.toLowerCase(); } return this.getAll().map(data => { const results: any = []; data.map(item => { // check for item in localStorage if (localStorage['person' + item.id]) { item = JSON.parse(localStorage['person' + item.id]); } if (JSON.stringify(item).toLowerCase().includes(q)) { results.push(item); } }); return results; }); } get(id: number) { return this.getAll().map(all => { if (localStorage['person' + id]) { return JSON.parse(localStorage['person' + id]); } return all.find(e => e.id === id); }); } save(person: Person) { localStorage['person' + person.id] = JSON.stringify(person); }
You can add CSS to src/app/edit/edit.component.css if you want to make the form look a bit better.
:host { display: block; padding: 0 20px; } button { margin-top: 10px; }
At this point, you should be able to search for a person and update their information.
The <form> in src/app/edit/edit.component.html calls a save() function to update a person’s data. You already implemented this above. The function calls a gotoList() function that appends the person’s name to the URL when sending the user back to the search screen.
gotoList() { if (this.person) { this.router.navigate(['/search', {term: this.person.name} ]); } else { this.router.navigate(['/search']); } }
Since the SearchComponent doesn’t execute a search automatically when you execute this URL, add the following logic to do so in its constructor.
import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs'; ... sub: Subscription; constructor(private searchService: SearchService, private route: ActivatedRoute) { this.sub = this.route.params.subscribe(params => { if (params['term']) { this.query = decodeURIComponent(params['term']); this.search(); } }); }
You’ll want to implement OnDestroy and define the ngOnDestroy method to clean up this subscription.
import { Component, OnInit, OnDestroy } from '@angular/core'; export class SearchComponent implements OnInit, OnDestroy { ... ngOnDestroy() { this.sub.unsubscribe(); } }
After making all these changes, you should be able to search/edit/update a person’s information. If it works – nice job!
Form Validation
One thing you might notice is you can clear any input element in the form and save it. At the very least, the name field should be required. Otherwise, there’s nothing to click on in the search results.
To make name required, modify edit.component.html to add a required attribute to the name <input>.
<input [(ngModel)]="editName" name="name" id="name" placeholder="name" required/>
You’ll also need to wrap everything in a <form> element. Add <form> after the <h3> tag and close it before the last </div>. You’ll also need to add an (ngSubmit) handler to the form and change the save button to be a regular submit button.
<h3></h3> <form (ngSubmit)="save()" ngNativeValidate> ... <button type="submit" id="save">Save</button> <button (click)="cancel()" id="cancel">Cancel</button> </form>
After making these changes, any field with a required attribute will be required.
In this screenshot, you might notice the address fields are blank. This is explained by the error in your console.
If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions. Example 1: <input [(ngModel)]="person.firstName" name="first"> Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">
To fix, add a name attribute to all the address fields. For example:
<address> <input [(ngModel)]="editAddress.street" name="street" id="street"><br/> <input [(ngModel)]="editAddress.city" name="city" id="city">, <input [(ngModel)]="editAddress.state" name="state" id="state" size="2"> <input [(ngModel)]="editAddress.zip" name="zip" id="zip" size="5"> </address>
Now values should display in all fields and name should be required.
If you want to provide your own validation messages instead of relying on the browser’s, complete the following steps:
Remove ngNativeValidate and add #editForm="ngForm" to the <form> element.
Add #name="ngModel" to the <input id="name"> element.
Add [disabled]="!editForm.form.valid" to the Save button.
Add the following under the name field to display a validation error.
<div [hidden]="name.valid || name.pristine" style="color: red"> Name is required </div>
To learn more about forms and validation, see Angular forms documentation.
Create an OpenID Connect App in Okta
OpenID Connect (OIDC) is built on top of the OAuth 2.0 protocol. It allows clients to verify the identity of the user and, as well as to obtain their basic profile information. To learn more, see http://j.mp/2yeLjkR.
To integrate Okta for user authentication, you’ll first need to register and create an OIDC application.
Login to your Okta account, or create one if you don’t have one. Navigate to Applications and click on the Add Application button. Select SPA and click Next. On the next page, specify http://localhost:4200 as a Base URI, Login redirect URI, and Logout redirect URI. Click Done and you should see settings like the following.
Install Manfred Steyer’s project to add OAuth 2 and OpenID Connect support using npm.
npm install --save angular-oauth2-oidc
Modify src/app/app.component.ts to import OAuthService and configure your app to use your Okta application’s settings.
import { OAuthService, JwksValidationHandler } from 'angular-oauth2-oidc'; ... constructor(private oauthService: OAuthService) { this.oauthService.redirectUri = window.location.origin; this.oauthService.clientId = '{client-id}'; this.oauthService.scope = 'openid profile email'; this.oauthService.issuer = 'http://j.mp/2xxH6p3'; this.oauthService.tokenValidationHandler = new JwksValidationHandler(); // Load Discovery Document and then try to login the user this.oauthService.loadDiscoveryDocument().then(() => { this.oauthService.tryLogin(); }); } ...
Create src/app/home/home.component.ts and configure it to have Login and Logout buttons.
import { Component } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; @Component({ template: ` <div *ngIf="givenName"> <h2>Welcome, !</h2> <button (click)="logout()">Logout</button> <p><a routerLink="/search" routerLinkActive="active">Search</a></p> </div> <div *ngIf="!givenName"> <button (click)="login()">Login</button> </div>` }) export class HomeComponent { constructor(private oauthService: OAuthService) { } login() { this.oauthService.initImplicitFlow(); } logout() { this.oauthService.logOut(); } get givenName() { const claims = this.oauthService.getIdentityClaims(); if (!claims) { return null; } return claims['name']; } }
Create src/app/shared/auth/auth.guard.service.ts to navigate to the HomeComponent if the user is not authenticated.
import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; import { OAuthService } from 'angular-oauth2-oidc'; @Injectable() export class AuthGuard implements CanActivate { constructor(private oauthService: OAuthService, private router: Router) {} canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { if (this.oauthService.hasValidIdToken()) { return true; } this.router.navigate(['/home']); return false; } }
Export AuthGuard in src/shared/index.ts:
export * from './auth/auth.guard.service';
Import the OAuthModule in src/app/app.module.ts, configure the new HomeComponent, and lock the /search and /edit routes down with the AuthGuard.
import { OAuthModule } from 'angular-oauth2-oidc'; import { HomeComponent } from './home/home.component'; import { SearchService, AuthGuard } from './shared'; const appRoutes: Routes = [ {path: 'search', component: SearchComponent, canActivate: [AuthGuard]}, {path: 'edit/:id', component: EditComponent, canActivate: [AuthGuard]}, {path: 'home', component: HomeComponent}, {path: '', redirectTo: 'home', pathMatch: 'full'}, {path: '**', redirectTo: 'home'} ]; @NgModule({ declarations: [ ... HomeComponent ], imports: [ ... OAuthModule.forRoot() ], providers: [ AuthGuard, SearchService ], bootstrap: [AppComponent] }) export class AppModule { }
After making these changes, you should be able to run ng serve and see a login button.
Click the Login button and sign-in with one of the people that’s configured in your Okta application.
After logging in, you’ll be able to click Search and view people’s information.
If it works – great! If you want to build your own login form in your app, continue reading to learn how to use the Okta Auth SDK with OAuthService.
Authentication with the Okta Auth SDK
The Okta Auth SDK builds on top of Otka’s Authentication API and OAuth 2.0 API to enable you to create a fully branded sign-in experience using JavaScript.
Install it using npm:
npm install @okta/okta-auth-js --save
Add a reference to this library’s main JavaScript file in .angular-cli.json:
"scripts": [ "../node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js" ],
The components in this section use Bootstrap CSS classes. Install Bootstrap 4.
npm install [email protected] --save
Modify src/styles.css to add a reference to Bootstrap’s CSS file.
@import "~bootstrap/dist/css/bootstrap.css";
Update src/app/app.component.html to use Bootstrap classes for its navbar and grid system.
<nav class="navbar navbar-light bg-secondary"> <a class="navbar-brand text-light" href="#">Welcome to !</a> </nav> <div class="container-fluid"> <router-outlet></router-outlet> </div>
Create src/app/shared/auth/okta.auth.wrapper.ts to wrap the Okta Auth SDK and integrate it with OAuthService. Its login() method uses OktaAuth to get a session token and exchange it for ID and access tokens.
import { OAuthService } from 'angular-oauth2-oidc'; import { Injectable } from '@angular/core'; declare const OktaAuth: any; @Injectable() export class OktaAuthWrapper { private authClient: any; constructor(private oauthService: OAuthService) { this.authClient = new OktaAuth({ url: this.oauthService.issuer }); } login(username: string, password: string): Promise<any> { return this.oauthService.createAndSaveNonce().then(nonce => { return this.authClient.signIn({ username: username, password: password }).then((response) => { if (response.status === 'SUCCESS') { return this.authClient.token.getWithoutPrompt({ clientId: this.oauthService.clientId, responseType: ['id_token', 'token'], scopes: ['openid', 'profile', 'email'], sessionToken: response.sessionToken, nonce: nonce, redirectUri: window.location.origin }) .then((tokens) => { const idToken = tokens[0].idToken; const accessToken = tokens[1].accessToken; const keyValuePair = `#id_token=${encodeURIComponent(idToken)}&access_token=${encodeURIComponent(accessToken)}`; return this.oauthService.tryLogin({ <1> customHashFragment: keyValuePair, disableOAuth2StateCheck: true }); }); } else { return Promise.reject('We cannot handle the ' + response.status + ' status'); } }); }); } }
In the above code, oauthService.tryLogin() parses and stores the idToken and accessToken so they can be retrieved using OAuthService.getIdToken() and OAuthService.getAccessToken().
Export OktaAuthWrapper in src/shared/index.ts:
export * from './auth/okta.auth.wrapper';
Add OktaAuthWrapper as a provider in app.module.ts.
import { SearchService, AuthGuard, OktaAuthWrapper } from './shared'; @NgModule({ ... providers: [ ... OktaAuthWrapper ], bootstrap: [AppComponent] })
Change HomeComponent to declare OktaAuth and modify its template so it has a button to login, as well as a sign-in form.
@Component({ template: ` <div *ngIf="givenName" class="col-12 mt-2"> <button (click)="logout()" class="btn btn-sm btn-outline-primary float-right">Logout</button> <h2>Welcome, !</h2> <p><a routerLink="/search" routerLinkActive="active">Search</a></p> </div> <div class="card mt-2" *ngIf="!givenName"> <div class="card-body"> <h4 class="card-title">Login with Authorization Server</h4> <button class="btn btn-primary" (click)="login()">Login</button> </div> </div> <div class="card mt-2" *ngIf="!givenName"> <div class="card-body"> <h4 class="card-title">Login with Username/Password</h4> <p class="alert alert-error" *ngIf="loginFailed"> Login wasn't successful. </p> <div class="form-group"> <label>Username</label> <input class="form-control" [(ngModel)]="username"> </div> <div class="form-group"> <label>Password</label> <input class="form-control" type="password" [(ngModel)]="password"> </div> <div class="form-group"> <button class="btn btn-primary" (click)="loginWithPassword()">Login</button> </div> </div> </div>` })
After making these changes, the HomeComponent should render as follows.
Add local variables for the username and password fields, import OktaAuthWrapper, and implement a loginWithPassword() method in HomeComponent.
import { OktaAuthWrapper } from '../shared'; ... username; password; constructor(private oauthService: OAuthService, private oktaAuthWrapper: OktaAuthWrapper) { } loginWithPassword() { this.oktaAuthWrapper.login(this.username, this.password) .then(_ => console.debug('logged in')) .catch(err => console.error('error logging in', err)); }
You should be able to sign in using the form, using one of your app’s registered users. After logging in, you’ll be able to click the Search link and view people’s information.
Angular + Okta
If everything works – congrats! If you encountered issues, please post a question to Stack Overflow with an okta tag, or hit me up on Twitter @mraible.
You can find a completed version of the application created in this blog post on GitHub. To learn more about security in Angular, see Angular’s Security documentation. If you’d like to learn more about OpenID Connect, I’d recommend watching the soothing video below.
VIDEO
Matt is a Java Champion, web developer, and Developer Advocate at Okta. He likes to code in both Java and Javascript, but has also had a lot of fun with TypeScript lately.
http://j.mp/2xxputu via SitePoint URL : http://j.mp/2c7PqoM
0 notes
Text
Ionic Angular Lazy Loading with Child Components
We have already discussed few articles on Ionic. Latest Ionic 3 came up with lazy loading concepts. Changing Ionic apps to use lazy loading significantly boost up the app performance. This actually improves the app speed, instead of loading everything in root application module file. This allows doing the work in sync with when your users want it to happen. This article explains to you how to modify the existing default Ionic app and apply lazy load concepts like working with providers, shared/child components. It process by loading chunks of code such as child components when it’s requested not when the app is loaded. Use this feature and enrich your application. Watch the video, you understand it better.
Install Latest Ionic & Cordova Update your Ionic using following command. Now it supports hotloading with IonicDevApp and lazyloading.
$npm install ionic cordova -g
Video Tutorial - Ionic Angular Lazy Loading with Child Components
youtube
Create Ionic Project with Tabs Let's create a Ionic default tabs project. This comes with default structure wit following compoenents.
$ionic start YourProjectName tabs
Default Project We are applying lazy loading features to this application. Getting started Go to src folder and modify app.module.ts app.module.ts Here we are dropping all the existing page component imports like home, about and contact.
import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
@NgModule({
declarations: [
MyApp
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
})
export class AppModule {}
Delete Pages Go to project folder and delete all the pages except tabs. We are going to modify the TabsPage later. Regenerate Pages Generate pages using latet Ionic version. This comes with lazy load modules.
$ionic g page Home $ionic g page About $ionic g page Contact
Newly Generated Pages If you notice new page components comes up with Ionic Page Module. This is going to support lazy loading. Create Module for Tabs We need to create the following file. This play key role for lazy loading page. tabs.moudle.ts Create this file inside tabs folder. It is very similar to home.module.ts
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { TabsPage } from './tabs';
@NgModule({
declarations: [
TabsPage,
],
imports: [
IonicPageModule.forChild(TabsPage),
],
})
export class HomePageModule {}
tabs.ts Drop all the page component imports, instead we are going to use page names and keep page name in quots link HomePage to "HomePage". Here IonicPage module will understand all of these page names.
import { Component } from "@angular/core";
import { IonicPage } from "ionic-angular";
@IonicPage()
@Component({
templateUrl: "tabs.html"
})
export class TabsPage {
tab1Root = "HomePage";
tab2Root = "AboutPage";
tab3Root = "ContactPage";
constructor() {}
}
app.components.ts Some way you have remove TabsPage component and replace the root page with name string "TabsPage".
import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
@Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = 'TabsPage';
constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
platform.ready().then(() => {
statusBar.styleDefault();
splashScreen.hide();
});
}
}
Working with Providers The provider is an injectable component or service. Here you can include the most commonly used functions like HTTP api calls etc. Generate providers using Ionic command and this will take care all the imports in app.module.ts
$ionic g provider Api $ionic g provider User
Note: Watch the video for provider.ts export file. app.module.ts App module will update with new providers. Here you have to include HttpModule for making API calls.
import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HttpModule } from "@angular/http";
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { ApiProvider, UserProvider } from '../providers/providers';
@NgModule({
declarations: [
MyApp
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
HttpModule
],
bootstrap: [IonicApp],
entryComponents: [
MyApp
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
ApiProvider,
UserProvider
]
})
export class AppModule {}
Working with Shared/Child Components In the Ionic project, the page is nothing but an angular component. Shared/Child component you can import into multiple pages. This comes with HTML template. Ionic command for generting components.
$ionic g component FollowButton $ionic g component DeleteButton
It will auto generate component.module.ts export file. component.module.ts Common import file for all the shared components.
import { NgModule } from "@angular/core";
import { FollowButtonComponent } from "./follow-button/follow-button";
import { IonicModule } from "ionic-angular";
import { DeleteButtonComponent } from "./delete-button/delete-button";
@NgModule({
declarations: [FollowButtonComponent, DeleteButtonComponent],
imports: [IonicModule],
exports: [FollowButtonComponent, DeleteButtonComponent]
})
export class ComponentsModule {}
How to Import Lazy load Child Components You can import shared components for importing comonent.module.ts home.moudle.ts Import ComponentModule export componets file and include it in imports.
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { HomePage } from './home';
import { ComponentsModule } from '../../components/components.module';
@NgModule({
declarations: [
HomePage,
],
imports: [
ComponentsModule,
IonicPageModule.forChild(HomePage),
],
})
export class HomePageModule {}
home.html Use component selector <follow-button> to call the Follow Button component. Here using name attribute initiating the data to the child compoent. For pusing dynamic data use [name] attribute. Here name is the input key.
<ion-header>
<ion-navbar>
<ion-title>home</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
Lazy loading
<follow-button name="home page" ></follow-button>
</ion-content>
Working with Input String Using @Input() module we can read the name attribute value. frined-button.ts Import Input module and declare input string "name".
import { Component, Input } from "@angular/core";
@Component({
selector: "follow-button",
templateUrl: "follow-button.html"
})
export class FollowButtonComponent {
@Input() name: String;
text: string;
constructor() {
console.log("Hello FollowButtonComponent Component");
this.text = "Follow Button";
}
action() {
console.log(this.name);
}
}
frined-button.html Implemented an action for priting input value in console.log
<button ion-button (click)="action()">
Video Tutorial - Ionic Angular Lazy Loading with Child Components
youtube
via 9lessons Programming Blog http://ift.tt/2C47vPi
0 notes
Photo
Understanding Component Architecture: Refactoring an Angular App
This article is part 2 of the SitePoint Angular 2+ Tutorial on how to create a CRUD App with the Angular CLI.
In part one we learned how to get our Todo application up and running and deploy it to GitHub pages. This worked just fine, but unfortunately the whole app was crammed into a single component.
In this article (part two) we will examine a more modular component architecture. We will look at how to break this single component into a structured tree of smaller components that are easier to understand, re-use and maintain.
You don't need to have followed part one of this tutorial, for part two to make sense. You can simply grab a copy of our repo, checkout the code from part one, and use that as a starting point. This is explained in more detail below.
A Quick Recap
So let's look at what we covered in part one in slightly more detail. We learned how to:
initialize our Todo application using the Angular CLI
create a Todo class to represent individual todos
create a TodoDataService service to create, update and remove todos
use the AppComponent component to display the user interface
deploy our application to GitHub pages
The application architecture of part 1 looked like this:
The components we discussed are marked with a red border.
In this second article we will delegate some of the work that AppComponent is doing to smaller components that are easier to understand, re-use and maintain.
We will create:
a TodoListComponent to display a list of todo's
a TodoListItemComponent to display a single todo
a TodoListHeaderComponent to create a new todo
a TodoListFooterComponent to show how many todo's are left
By the end of this article, you will understand:
the basics of Angular component architecture
how you can pass data into a component using property bindings
how you can listen for events emitted by a component using event listeners
why it is a good practice to split components into smaller reusable components
the difference between smart and dumb components and why keeping components dumb is a good practice
So let's get started!
Up and Running
The first thing you will need to follow along with this article is the latest version of the Angular CLI. You can install this with the following command:
npm install -g @angular/cli@latest
If you need to remove a previous version of of the Angular CLI, here's how:
npm uninstall -g @angular/cli angular-cli npm cache clean npm install -g @angular/cli@latest
After that you'll need a copy of the code from part one. This is available at http://ift.tt/2mpeXuK. Each article in this series has a corresponding tag in the repository so you can switch back and forth between the different states of the application.
The code that we ended with in part one and that we start with in this article is tagged as part-1. The code that we end this article with is tagged as part-2.
You can think of tags like an alias to a specific commit id. You can switch between them using git checkout. You can read more on that here.
So, to get up and running (the the latest version of the Angular CLI installed) we would do:
git clone [email protected]:sitepoint-editors/angular-todo-app.git cd angular-todo-app npm install git checkout part-1 ng serve
Then visit http://localhost:4200/. If all is well, you should see the working Todo app.
The Original AppComponent
Let's open src/app/app.component.html and have a look at the AppComponent that we finished with in part one:
<section class="todoapp"> <header class="header"> <h1>Todos</h1> <input class="new-todo" placeholder="What needs to be done?" autofocus="" [(ngModel)]="newTodo.title" (keyup.enter)="addTodo()"> </header> <section class="main" *ngIf="todos.length > 0"> <ul class="todo-list"> <li *ngFor="let todo of todos" [class.completed]="todo.complete"> <div class="view"> <input class="toggle" type="checkbox" (click)="toggleTodoComplete(todo)" [checked]="todo.complete"> <label></label> <button class="destroy" (click)="removeTodo(todo)"></button> </div> </li> </ul> </section> <footer class="footer" *ngIf="todos.length > 0"> <span class="todo-count"><strong></strong> left</span> </footer> </section>
and its corresponding class in src/app/app.component.ts:
import {Component} from '@angular/core'; import {Todo} from './todo'; import {TodoDataService} from './todo-data.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers: [TodoDataService] }) export class AppComponent { newTodo: Todo = new Todo(); constructor(private todoDataService: TodoDataService) { } addTodo() { this.todoDataService.addTodo(this.newTodo); this.newTodo = new Todo(); } toggleTodoComplete(todo: Todo) { this.todoDataService.toggleTodoComplete(todo); } removeTodo(todo: Todo) { this.todoDataService.deleteTodoById(todo.id); } get todos() { return this.todoDataService.getAllTodos(); } }
Although our AppComponent works fine technically, keeping all code in one big component does not scale well and is not recommended.
Adding more features to our Todo application would make the AppComponent larger and more complex, making it harder to understand and maintain.
Therefore it is recommended to delegate functionality to smaller components. Ideally the smaller components should be configurable so that we don't have to rewrite their code when the business logic changes.
For example: in part three of this series, we will update the TodoDataService to communicate with a REST API and we want to make sure that we will not have to change any of the smaller components when we refactor the TodoDataService.
If we look at the AppComponent template we can extract its underlying structure as:
<!-- header that lets us create new todo --> <header></header> <!-- list that displays todos --> <ul class="todo-list"> <!-- list item that displays single todo --> <li>Todo 1</li> <!-- list item that displays single todo --> <li>Todo 2</li> </ul> <!-- footer that displays statistics --> <footer></footer>
If we translate this structure to Angular component names, we get:
<!-- TodoListHeaderComponent that lets us create new todo --> <app-todo-list-header></app-todo-list-header> <!-- TodoListComponent that displays todos --> <app-todo-list> <!-- TodoListItemComponent that displays single todo --> <app-todo-list-item></app-todo-list-item> <!-- TodoListItemComponent that displays single todo --> <app-todo-list-item></app-todo-list-item> </app-todo-list> <!-- TodoListFooterComponent that displays statistics --> <app-todo-list-footer></app-todo-list-footer>
Let's see how we can use the power of Angular's component driven development to make this happen.
A More Modular Component Architecture — Creating the TodoListHeaderComponent
Let's start by creating the TodoListHeader component.
From the root of our project, we use Angular CLI to generate the component for us:
$ ng generate component todo-list-header
which generates the following files for us:
create src/app/todo-list-header/todo-list-header.component.css create src/app/todo-list-header/todo-list-header.component.html create src/app/todo-list-header/todo-list-header.component.spec.ts create src/app/todo-list-header/todo-list-header.component.ts
and automatically adds TodoListHeaderComponent to the AppModule declarations:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { AppComponent } from './app.component'; // Automatically imported by Angular CLI import { TodoListHeaderComponent } from './todo-list-header/todo-list-header.component'; @NgModule({ declarations: [ AppComponent, // Automitically added by Angular CLI TodoListHeaderComponent ], imports: [ BrowserModule, FormsModule, HttpModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Adding a component to the module declarations is required to make sure that all view templates in the module can use it the component. Angular CLI conveniently added TodoListHeaderComponent for us so we don't have to add it manually.
If TodoListHeaderComponent was not in the declarations and we used it in a view template, Angular would throw the following error:
Error: Uncaught (in promise): Error: Template parse errors: 'app-todo-list-header' is not a known element: 1. If 'app-todo-list-header' is an Angular component, then verify that it is part of this module. 2. If 'app-todo-list-header' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message.
To learn more about module declarations, make sure to check out the Angular Module FAQ.
Now that we have all files generated for our new TodoListHeaderComponent, we can move the <header> element from src/app/app.component.html to src/app/todo-list-header/todo-list-header.component.html:
<header class="header"> <h1>Todos</h1> <input class="new-todo" placeholder="What needs to be done?" autofocus="" [(ngModel)]="newTodo.title" (keyup.enter)="addTodo()"> </header>
and add the corresponding logic to src/app/todo-list-header/todo-list-header.component.ts:
import { Component, Output, EventEmitter } from '@angular/core'; import { Todo } from '../todo'; @Component({ selector: 'app-todo-list-header', templateUrl: './todo-list-header.component.html', styleUrls: ['./todo-list-header.component.css'] }) export class TodoListHeaderComponent { newTodo: Todo = new Todo(); @Output() add: EventEmitter<Todo> = new EventEmitter(); constructor() { } addTodo() { this.add.emit(this.newTodo); this.newTodo = new Todo(); } }
Instead of injecting the TodoDataService in our new TodoListHeaderComponent to save the new todo, we emit an add event and pass the new todo as an argument.
We already learned that the Angular template syntax allows us to attach a handler to an event. For example, the following code:
Continue reading %Understanding Component Architecture: Refactoring an Angular App%
by Jurgen Van de Moere via SitePoint http://ift.tt/2nkPTtO
0 notes