Wednesday, 29 May 2019
Your website will have the following features:
Friday, 21 July 2017
How To Make Fidget Spinner
Are you looking for Fidget Spinner, this post will explain you how to create a Fidget Spinner using Jquery, HTML and CSS, I want to explain how to design Fidget Spinner with CSS, HTML and Jquery. Fidget Spinner help you to spin Like Real Fidget Spinner, Just take a quick look at these four steps, use it and make your own Fidget Spinner.
CSS Code
CSS3 KeyAnimation
HTML Code
Layout divided into five parts are BG, everything and holder ,spinner. Here handle
<div class="bg"></div>
<div class="everything">
<div class="holder">
<div class="spinner">
<img src="fidgetspinner_r.png">
</div>
<div class="handle"></div>
</div>
</div>
<div class="everything">
<div class="holder">
<div class="spinner">
<img src="fidgetspinner_r.png">
</div>
<div class="handle"></div>
</div>
</div>
CSS Code
body,html {
width: 100%;
height: 100%;
border: 0;
padding: 0;
margin: 0;
overflow: hidden
}
.bodge {
position: absolute;
bottom: 10px;
right: 10px;
color: #000;
z-index: 99
}
.bodge a {
font-style: italic;
color: #000
}
.bg {
width: 100%;
height: 100%;
position: absolute;
z-index: 0;
background: -moz-linear-gradient(-45deg,rgba(0,0,0,0.3) 0,rgba(0,0,0,0) 100%);
background: -webkit-linear-gradient(-45deg,rgba(0,0,0,0.3) 0,rgba(0,0,0,0) 100%);
background: linear-gradient(135deg,rgba(0,0,0,0.3) 0,rgba(0,0,0,0) 100%)
}
.everything {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%
}
.spinner img {
width: 100%
}
.holder,.spinner {
width: 300px;
height: 300px;
position: relative
}
.handle {
width: 70px;
height: 70px;
position: absolute;
top: 115px;
left: 115px;
z-index: 1
}
width: 100%;
height: 100%;
border: 0;
padding: 0;
margin: 0;
overflow: hidden
}
.bodge {
position: absolute;
bottom: 10px;
right: 10px;
color: #000;
z-index: 99
}
.bodge a {
font-style: italic;
color: #000
}
.bg {
width: 100%;
height: 100%;
position: absolute;
z-index: 0;
background: -moz-linear-gradient(-45deg,rgba(0,0,0,0.3) 0,rgba(0,0,0,0) 100%);
background: -webkit-linear-gradient(-45deg,rgba(0,0,0,0.3) 0,rgba(0,0,0,0) 100%);
background: linear-gradient(135deg,rgba(0,0,0,0.3) 0,rgba(0,0,0,0) 100%)
}
.everything {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%
}
.spinner img {
width: 100%
}
.holder,.spinner {
width: 300px;
height: 300px;
position: relative
}
.handle {
width: 70px;
height: 70px;
position: absolute;
top: 115px;
left: 115px;
z-index: 1
}
CSS3 KeyAnimation
@media screen and (min-width: 370px) and (max-width:499px) {
.holder,.spinner {
width:360px;
height: 360px;
position: relative
}
.handle {
width: 80px;
height: 80px;
position: absolute;
top: 140px;
left: 140px;
z-index: 1
}
}
@media screen and (min-width: 500px) {
.holder,.spinner {
width:500px;
height: 500px;
position: relative
}
.handle {
width: 100px;
height: 100px;
position: absolute;
top: 200px;
left: 200px;
z-index: 1
}
}
JavaScript
.holder,.spinner {
width:360px;
height: 360px;
position: relative
}
.handle {
width: 80px;
height: 80px;
position: absolute;
top: 140px;
left: 140px;
z-index: 1
}
}
@media screen and (min-width: 500px) {
.holder,.spinner {
width:500px;
height: 500px;
position: relative
}
.handle {
width: 100px;
height: 100px;
position: absolute;
top: 200px;
left: 200px;
z-index: 1
}
}
function resizeMe() {
initialOffset = $(".handle").position().top
}
function spin() {
$(".handle").pep({
drag: updatePos,
easing: updatePos
}),
initialOffset = $(".handle").position().top,
spinner = $(".spinner").propeller({
inertia: .999,
speed: .5,
onDragStop: function() {
backgroundInit = !0
},
onDragStart: function() {
backgroundInit = !1
},
onRotate: function() {
// updateBackground(this.speed)
}
})
}
function updateBackground(t) {
var e = "rgb(" + Math.floor(256 * Math.random()) + "," + Math.floor(256 * Math.random()) + "," + Math.floor(256 * Math.random()) + ")";
if (!backgroundAnimating && backgroundInit) {
var n = Math.abs(1e3 - 10 * Math.abs(t));
backgroundAnimating = !0,
$("body").animate({
backgroundColor: e
}, n, function() {
backgroundAnimating = !1
})
}
}
function doDrag(t, e) {
onDragStart,
updatePos(t, e)
}
function updatePos(t, e) {
var n = $(e.el);
$(".spinner").css({
top: n.position().top - initialOffset,
left: n.position().left - initialOffset
})
}
var initialOffset = 0, backgroundInit = !1, backgroundAnimating = !1, spinner;
initialOffset = $(".handle").position().top
}
function spin() {
$(".handle").pep({
drag: updatePos,
easing: updatePos
}),
initialOffset = $(".handle").position().top,
spinner = $(".spinner").propeller({
inertia: .999,
speed: .5,
onDragStop: function() {
backgroundInit = !0
},
onDragStart: function() {
backgroundInit = !1
},
onRotate: function() {
// updateBackground(this.speed)
}
})
}
function updateBackground(t) {
var e = "rgb(" + Math.floor(256 * Math.random()) + "," + Math.floor(256 * Math.random()) + "," + Math.floor(256 * Math.random()) + ")";
if (!backgroundAnimating && backgroundInit) {
var n = Math.abs(1e3 - 10 * Math.abs(t));
backgroundAnimating = !0,
$("body").animate({
backgroundColor: e
}, n, function() {
backgroundAnimating = !1
})
}
}
function doDrag(t, e) {
onDragStart,
updatePos(t, e)
}
function updatePos(t, e) {
var n = $(e.el);
$(".spinner").css({
top: n.position().top - initialOffset,
left: n.position().left - initialOffset
})
}
var initialOffset = 0, backgroundInit = !1, backgroundAnimating = !1, spinner;
Categories:
How To Make Fidget Spinner
javascript
Jquery
Saturday, 15 July 2017
Multiple reCAPTCHA Implementation on Same Page Sample
Page with multiple forms always need multiple reCAPTCHA for spam validation.
With Google new reCAPTCHA library "I'm not a robot" and Javascript parameter you can simply implement this multiple validation.
Needables:
1) Google reCAPCTHA Javascript URL
2) Following Implementation steps.The difference between automatic reCAPTCHA loading and explicit manual loading is the following script with onload callback funtion.
For Manual (or Multiple reCAPTCHA's in a page)
<script src="https://www.google.com/recaptcha/api.js?onload=myCallBack&render=explicit" async defer></script>
- onload = your local javascript callback function
- render = explicit
Html Form Code
<div class="container"> <div class="col-md-6"> <form class="form-signin" role="form" action="validateform.php" method="POST"> <div id="status"> </div> <h2 class="form-signin-heading">Please sign in</h2> <label for="inputEmail" class="sr-only">Email address</label> <input type="email" id="inputEmail" value="mycodde@test.com" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" id="inputPassword" value="rashid" class="form-control" placeholder="Password" required> <div id="recaptcha1"></div> <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> </form> </div> <div class="col-md-6"> <form class="form-signin" role="form" action="validateform.php" method="POST"> <div id="status"> </div> <h2 class="form-signin-heading">Sign Up Form</h2> <label for="inputEmail" class="sr-only">Email address</label> <input type="email" id="inputEmail" value="mycodde@test.com" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" id="inputPassword" value="rashid" class="form-control" placeholder="Password" required> <div id="recaptcha2"></div> <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> </form> </div> </div> <!-- /container -->
Javscript Code
<script src="https://www.google.com/recaptcha/api.js?onload=myCallBack&render=explicit" async defer></script> <script> var recaptcha1; var recaptcha2; var myCallBack = function() { //Render the recaptcha1 on the element with ID "recaptcha1" recaptcha1 = grecaptcha.render('recaptcha1', { 'sitekey' : '6Lc_0f4SAAAAAF9ZA', //Replace this with your Site key 'theme' : 'light' }); //Render the recaptcha2 on the element with ID "recaptcha2" recaptcha2 = grecaptcha.render('recaptcha2', { 'sitekey' : '6Lc_0f4SAAAAAF9ZA', //Replace this with your Site key 'theme' : 'dark' }); }; </script>
Thats it.
Sunday, 21 May 2017
What is JavaScript?

As per Wikipedia,
JavaScript is a high-level, dynamic, untyped, and interpreted
programming language. Alongside HTML and CSS, it is one of the three
core technologies of World Wide Web content production. The majority of
websites employ it and it is supported by all modern Web browsers
without plug-ins. It also support object-oriented, imperative, and
functional programming styles. It has an API for working with text,
arrays, dates and regular expressions, but does not include any I/O,
such as networking, storage, or graphics facilities, relying for these
upon the host environment in which it is embedded.
Why every programmer should learn JavaScript?
Demand - As per GitHub and StackOverflow, JavaScript is more popular than any other languages and number one computer language till date. JavaScript's matures and things like Node.js become increasingly viable options, the demand for JavaScript programmers will continue to increase. JavaScript already surpasses C# as rated by demand, and is surpassed only by Java.
Higher paid - JavaScript pays better than C# but still Java pays a bit better right now. But as demand for JavaScript grows, we can expect the pay to increase as well. While the demand for JavaScript is evident, it is obvious that several languages that have a smaller demand actually pay better. I suspect this is because many organizations still think of JavaScript as the language that anyone can use. It will be a very painful lesson when they find out that "Anyone can program in JavaScript" really means, "Anyone can write crappy code in JavaScript".
JavaScript is Maturing - With the recent commitment of the standards committee to release a new JavaScript standard every year, it is clear that the amount of Syntactic Sugar that will be added on to JavaScript is going to be increasing every year for a while now. One of the best features JavaScript is the ability to use the async and await keywords in code to eliminate callback hell.
The browsers are also continually improving how they handle JavaScript code. In the future when browsers not only cache the JavaScript files, but cache the compiled version of the JavaScript files. Bringing us closer to near binary speed.
JavaScript Programmers Are More Equal Than Others - Many people who call themselves JavaScript programmers, but don't know the basics. And that is today. Imagine what this is going to look like three to five years from now. And don't forget that a lot of the tooling to support profiling and memory leaks is just at its infancy. If you have those skills today, and you have marketed yourself well, you are already realizing that a lot of what I'm saying here is true.
Frameworks Are Maturing - With the new version of Angular in the works, Aurelia in the works as an alternative. Commercial products such as Scencha's EXTjs. Node.js for server side programing. Node.js for server side programing. And others No one can say that it is too hard to develop real applications using JavaScript. Even, you could write a desktop application that ran using nothing but JavaScript.
JavaScript Runs Everywhere - JavaScript runs on every major browser on every major platform. It runs on the server side on every major operating system. Anyone writing a web site today of any major functionality is going to need someone who knows JavaScript to write the front end. It doesn't matter what the back end code was written in be it Java, PHP, .NET, Node.js or something else, the client side is going to need a JavaScript developer.
JavaScript is a Compiled Language - It may shock you to know that, technically, JavaScript is a compiled language. This has two implications. First, once the code is compiled, it is possible for it to run as fast as any other executable. Second, it is technically possible to write tooling for JavaScript that would create a binary file that does not need to be recompiled every time the code is loaded into memory.
JavaScript will dominate, but no one will write it - Future of JavaScript is different than others. If we don't write JavaScript, who will? Transcoding robots, that’s who. We'll write our code in any of a dozen dialects and the transcoding robots will turn it into something that the browser or Node.js understands. More and more code on GitHub can't run without being "compiled" by something. The most prominent are pinky-saving dialects, such as TypeScript and CoffeeScript, that strip away much of the punctuation that bothers some programmers. These are only the beginning because clever programmers have written transcoders for languages as diverse as Cobol, Java, Lisp, and C. All of them can now run in your browser after being lovingly translated and optimized for fast delivery and parsing.
Why every programmer should learn JavaScript?
Demand - As per GitHub and StackOverflow, JavaScript is more popular than any other languages and number one computer language till date. JavaScript's matures and things like Node.js become increasingly viable options, the demand for JavaScript programmers will continue to increase. JavaScript already surpasses C# as rated by demand, and is surpassed only by Java.
Higher paid - JavaScript pays better than C# but still Java pays a bit better right now. But as demand for JavaScript grows, we can expect the pay to increase as well. While the demand for JavaScript is evident, it is obvious that several languages that have a smaller demand actually pay better. I suspect this is because many organizations still think of JavaScript as the language that anyone can use. It will be a very painful lesson when they find out that "Anyone can program in JavaScript" really means, "Anyone can write crappy code in JavaScript".
JavaScript is Maturing - With the recent commitment of the standards committee to release a new JavaScript standard every year, it is clear that the amount of Syntactic Sugar that will be added on to JavaScript is going to be increasing every year for a while now. One of the best features JavaScript is the ability to use the async and await keywords in code to eliminate callback hell.
The browsers are also continually improving how they handle JavaScript code. In the future when browsers not only cache the JavaScript files, but cache the compiled version of the JavaScript files. Bringing us closer to near binary speed.
JavaScript Programmers Are More Equal Than Others - Many people who call themselves JavaScript programmers, but don't know the basics. And that is today. Imagine what this is going to look like three to five years from now. And don't forget that a lot of the tooling to support profiling and memory leaks is just at its infancy. If you have those skills today, and you have marketed yourself well, you are already realizing that a lot of what I'm saying here is true.
Frameworks Are Maturing - With the new version of Angular in the works, Aurelia in the works as an alternative. Commercial products such as Scencha's EXTjs. Node.js for server side programing. Node.js for server side programing. And others No one can say that it is too hard to develop real applications using JavaScript. Even, you could write a desktop application that ran using nothing but JavaScript.
JavaScript Runs Everywhere - JavaScript runs on every major browser on every major platform. It runs on the server side on every major operating system. Anyone writing a web site today of any major functionality is going to need someone who knows JavaScript to write the front end. It doesn't matter what the back end code was written in be it Java, PHP, .NET, Node.js or something else, the client side is going to need a JavaScript developer.
JavaScript is a Compiled Language - It may shock you to know that, technically, JavaScript is a compiled language. This has two implications. First, once the code is compiled, it is possible for it to run as fast as any other executable. Second, it is technically possible to write tooling for JavaScript that would create a binary file that does not need to be recompiled every time the code is loaded into memory.
JavaScript will dominate, but no one will write it - Future of JavaScript is different than others. If we don't write JavaScript, who will? Transcoding robots, that’s who. We'll write our code in any of a dozen dialects and the transcoding robots will turn it into something that the browser or Node.js understands. More and more code on GitHub can't run without being "compiled" by something. The most prominent are pinky-saving dialects, such as TypeScript and CoffeeScript, that strip away much of the punctuation that bothers some programmers. These are only the beginning because clever programmers have written transcoders for languages as diverse as Cobol, Java, Lisp, and C. All of them can now run in your browser after being lovingly translated and optimized for fast delivery and parsing.
Categories:
javascript
TechTopic
What is JavaScript?
Saturday, 6 May 2017
File Uploads in Angular with a Node and Hapi Backend

# File Upload UI & API
File upload consists of two parts: the UI (front-end) and the API (back-end). We will be using Angular to handle the UI part. We need a backend application to accept the uploaded files. You may follow the backend tutorials or download and run either one of these server side application to handle file upload for your backend:-- File upload with Hapi.js: https://scotch.io/bar-talk/handling-file-uploads-with-hapi-js, or
- File upload with Express + Multer: https://scotch.io/tutorials/express-file-uploads-with-multer, or
- Switch to any cloud solution of your choice (Amazon S3, Google Drive, etc).
# File Upload Component HTML
Alright, let's start creating our Angular file upload component.<!-- page-file-upload.component.html -->
<div>
<!--UPLOAD-->
<form #f="ngForm" enctype="multipart/form-data" novalidate
*ngIf="currentStatus === STATUS_INITIAL || currentStatus === STATUS_SAVING">
<h1>Upload images</h1>
<div class="dropbox">
<input type="file" multiple
[name]="uploadFieldName" (change)="filesChange($event.target.name, $event.target.files)"
[disabled]="currentStatus === STATUS_SAVING" accept="image/*" #photos>
<p *ngIf="currentStatus === STATUS_INITIAL">
Drag your file(s) here to begin<br>
or click to browse
</p>
<p *ngIf="currentStatus === STATUS_SAVING">
Uploading {{ photos.files.length }} files...
</p>
</div>
</form>
</div>
Notes:-- Our upload form will have a few statuses: STATUS_INITIAL, STATUS_SAVING, STATUS_SUCCESS, STATUS_FAILED, the variable name is pretty expressive themselves.
- We will display the upload form when the status is initial or saving.
- The form attribute
enctype="multipart/form-data"
is important. To enable file upload, this attribute must be set. Learn more about enctype here. - We have a file input
<input type="file" />
to accept file upload. The propertymultiple
indicate it's allow multiple file upload. Remove it for single file upload. - We will handle the file input
change
event. Whenever the file input change (someone drop or select files), we will trigger thefilesChange
function and pass in the control name and selected files$event.target.files
, and then upload to server. - We limit the file input to accept images only with the attribute
accept="image/*"
. - The file input will be disabled during upload, so user can only drop / select files again after upload complete.
- We set a template variable
#photos
to the file input. This gives us a reference to the file input control. Later, you can see we use thephotos
variable in displaying number of files uploadingUploading {{ photos.files.length }} files...
.
# Style our File Upload Component
Now, that's the interesting part. Currently, our component look like this:
We need to transform it to look like this:

Let's style it!
/* page-file-upload.component.css */
.dropbox {
outline: 2px dashed grey; /* the dash box */
outline-offset: -10px;
background: lightcyan;
color: dimgray;
padding: 10px 10px;
min-height: 200px; /* minimum height */
position: relative;
cursor: pointer;
}
.dropbox:hover {
background: lightblue; /* when mouse over to the drop zone, change color */
}
input[type="file"] {
opacity: 0; /* invisible but it's there! */
width: 100%;
height: 200px;
position: absolute;
cursor: pointer;
}
.dropbox p {
font-size: 1.2em;
text-align: center;
padding: 50px 0;
}
With only few lines of css, our component looks prettier now.Notes:-
- We make the file input invisible by applying
opacity: 0
style. This doesn't hide the file input, it just make it invisible. - Then, we style the file input parent element, the
dropbox
css class. We make it look like a drop file zone surround with dash. - Then, we align the text inside dropbox to center.
# File Upload Component Code
// page-file-upload.component.ts
import { Component } from '@angular/core';
import { FileUploadService } from './file-upload.service'; // we will create this next!
@Component({
selector: 'page-file-upload',
templateUrl: './page-file-upload.component.html',
styleUrls: ['./page-file-upload.component.css']
})
export class PageFileUploadComponent {
uploadedFiles = [];
uploadError;
currentStatus: number;
uploadFieldName = 'photos';
readonly STATUS_INITIAL = 0;
readonly STATUS_SAVING = 1;
readonly STATUS_SUCCESS = 2;
readonly STATUS_FAILED = 3;
constructor(private _svc: FileUploadService) {
this.reset(); // set initial state
}
filesChange(fieldName: string, fileList: FileList) {
// handle file changes
const formData = new FormData();
if (!fileList.length) return;
// append the files to FormData
Array
.from(Array(fileList.length).keys())
.map(x => {
formData.append(fieldName, fileList[x], fileList[x].name);
});
// save it
this.save(formData);
}
reset() {
this.currentStatus = this.STATUS_INITIAL;
this.uploadedFiles = [];
this.uploadError = null;
}
save(formData: FormData) {
// upload data to the server
this.currentStatus = this.STATUS_SAVING;
this._svc.upload(formData)
.take(1)
.delay(1500) // DEV ONLY: delay 1.5s to see the changes
.subscribe(x => {
this.uploadedFiles = [].concat(x);
this.currentStatus = this.STATUS_SUCCESS;
}, err => {
this.uploadError = err;
this.currentStatus = this.STATUS_FAILED;
})
}
}
Notes:-- Later on, we will call the Hapi.js file upload API to upload images, the API accept a field call
photos
. That's our file input field name. - We handle the file changes with the
filesChange
function.FileList
is an object returned by the files property of the HTML element. It allow us to access the list of files selected with the element. Learn more [here]((https://developer.mozilla.org/en/docs/Web/API/FileList). - We then create a new
FormData
, and append all ourphotos
files to it.FormData
interface provides a way to easily construct a set of key/value pairs representing form fields and their values. Learn more here. - The
save
function will call our file upload service (hang on, we will create the service next!). We also set the status according to the result.
# File Upload Service
// file-upload.service.ts
import { Injectable } from '@angular/core';
import { Http, RequestOptionsArgs, Headers } from '@angular/http';
@Injectable()
export class FileUploadService {
baseUrl = 'http://localhost:3001'; // our local Hapi Js API
constructor(private _http: Http) { }
upload(formData) {
const url = `${this.baseUrl}/photos/upload`;
return this._http.post(url, formData)
.map(x => x.json())
.map((x: any[]) => x
// add a new field url to be used in UI later
.map(item => Object
.assign({}, item, { url: `${this.baseUrl}/images/${item.id}` }))
);
}
}
Nothing much, the code is pretty expressive itself. We upload the files, wait for the result, map it accordingly.Now wire up your component and service to module, usually
app.module.ts
, and run it.# Display Success and Failed Result
We can upload the files successfully now. However, there's no indication in UI. Let's update our HTML.<!-- page-file-upload.component.html -->
<div>
<!--UPLOAD-->
...
<!--SUCCESS-->
<div class="margin-20" *ngIf="currentStatus === STATUS_SUCCESS">
<h2>Uploaded {{ uploadedFiles.length }} file(s) successfully.</h2>
<p>
<a href="javascript:void(0)" (click)="reset()">Upload again</a>
</p>
<ul class="list-unstyled">
<li *ngFor="let item of uploadedFiles">
<img [src]="item.url" class="img-responsive img-thumbnail"
[alt]="item.originalName">
</li>
</ul>
</div>
<!--FAILED-->
<div class="margin-20" *ngIf="currentStatus === STATUS_FAILED">
<h2>Uploaded failed.</h2>
<p>
<a href="javascript:void(0)" (click)="reset()">Try again</a>
</p>
<pre>{{ uploadError | json }}</pre>
</div>
</div>
Notes:-- Display the uploaded image when upload successfully.
- Display the error message when upload failed.
# Fake the Upload in Front-end
If you are lazy to start the back-end application (Hapi, Express, etc) to handle file upload. Here is a fake service to replace the file upload service.// file-upload.fake.service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class FileUploadFakeService {
upload(formData: any) {
const photos: any[] = formData.getAll('photos');
const promises = photos.map((x: File) => this.getImage(x)
.then(img => ({
id: img,
originalName: x.name,
fileName: x.name,
url: img
})));
return Observable.fromPromise(Promise.all(promises));
}
private getImage(file: File) {
return new Promise((resolve, reject) => {
const fReader = new FileReader();
const img = document.createElement('img');
fReader.onload = () => {
img.src = fReader.result;
resolve(this.getBase64Image(img));
}
fReader.readAsDataURL(file);
})
}
private getBase64Image(img) {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const dataURL = canvas.toDataURL('image/png');
return dataURL;
}
}
Came across this solution in this Stackoverflow post. Pretty useful. My online demo is using this service. Basically, what the code do is read the source, draw it in canvas, and save it as data url with the canvas
toDataURL
function. Learn more about canvas here.If you realize, our fake service has a same public interface as the real file upload service, both has
upload
function and return list of files. This is important for the next step, swap the real file upload service with the fake one.# Swap the Real File Upload with the Fake Service
First you might think that to use the fake service, you need to register the fake service in module, and import it in our file upload component like how we do usually. However, there's a quicker way, with Angular dependency injection (DI). Let's look at our App module.// app.module.ts
...
import { PageFileUploadComponent, FileUploadFakeService,
FileUploadService } from './file-upload';
@NgModule({
...
providers: [
// FileUploadService, // normally we do this, comment it, we do the below instead
{ provide: FileUploadService, useClass: FileUploadFakeService }, // we can do this instead
],
...
})
export class AppModule { }
With this, you don't need to change your component code, stop your
backend API, refresh the browser, you should see our app is still
working, calling fake service instead. In short,
Providers: [FileUploadService]
is the short form of Providers: [{ provide: FileUploadService, useClass: FileUploadService }]
. Therefore, as long as we have another class with similar interface, we can swap it easily.Angular DI is powerful. We'll leave that for another post.