Full Trust European Hosting

BLOG about Full Trust Hosting and Its Technology - Dedicated to European Windows Hosting Customer

AngularJS Hosting Europe - HostForLIFE :: How To Create Voice Recognition Using Ngx-Speech-Recognition In Angular?

clock September 16, 2022 06:52 by author Peter

In this article, we are going to see how voice recognition can translate spoken words into text using closed captions to enable a person with hearing loss to understand what others are saying. It's most useful for students, employees, and client communications purposes rather than using voice commands instead of typing.

First, we have created a basic Angular application using Angular CLI.

Here I have used ngx Speech Recognition for custom plugins or we can create a separate library inside the application, and be able to use the newly created library.  

Please refer to this link for angular custom library creations.

I have used Ngx Speech Recognition service library from the applications created as ngx-speech-recognition-test.

How to Create Voice Recognition using Ngx-Speech-Recognition in Angular

Then created main and sub-components. The main components are just using some project-related purpose or whatever content we need to add this main component. If you don’t need it, please ignore it. In the sub-components, we used the voice recognition part. Please check the following code.

Here I have added all sub-components codes.

Sub.component.ts

import {
    Component
} from '@angular/core';
import {
    ColorGrammar
} from './sub.component.grammar';
import {
    SpeechRecognitionLang,
    SpeechRecognitionMaxAlternatives,
    SpeechRecognitionGrammars,
    SpeechRecognitionService,
} from '../../../../../projects/ngx-speech-recognition-test/src/public_api';
@Component({
    selector: 'test-sub',
    templateUrl: './sub.component.html',
    styleUrls: ['./sub.component.css'],
    providers: [
        // Dependency Inject to SpeechRecognitionService
        // like this.
        {
            provide: SpeechRecognitionLang,
            useValue: 'en-US',
        }, {
            provide: SpeechRecognitionMaxAlternatives,
            useValue: 1,
        }, {
            provide: SpeechRecognitionGrammars,
            useValue: ColorGrammar,
        },
        SpeechRecognitionService,
    ],
})
export class SubComponent {
    public started = false;
    public message = '';
    constructor(private service: SpeechRecognitionService) {
        // Dependency The injected services are displayed on the console.
        // Dependence was resolved from SubComponent's provider.
        this.service.onstart = (e) => {
            console.log('voice start');
        };
        this.service.onresult = (e) => {
            this.message = e.results[0].item(0).transcript;
            console.log('voice message result', this.message, e);
        };
    }
    start() {
        this.started = true;
        this.service.start();
    }
    stop() {
        this.started = false;
        this.service.stop();
    }
}


SpeechRecognitionLang, SpeechRecognitionMaxAlternatives, SpeechRecognitionGrammars and SpeechRecognitionService all imported from ngx-speech-recognition-test.

We need to inject SpeechRecognitionServices. SpeechRecognitionLang provides mapping, we can map language code mentioned 'en-US'

SpeechRecognitionMaxAlternatives is Recognition voice count. I have marked 1.  

SpeechRecognitionGrammars purpose checked to translate text for grammar validations.  

ColorGrammar(Sub.component.grammar.ts). All the setup configurations are in the above codes.

Sub.component.grammar.ts
Sub.component.grammar.ts
/**
 * @see https://developer.mozilla.org/ja/docs/Web/API/SpeechGrammarList#Examples
 */
export const ColorGrammar = new SpeechGrammarList();
ColorGrammar.addFromString(`#JSGF V1.0;
grammar colors;
public <color> = aqua | azure | beige | bisque |
  black | blue | brown | chocolate | coral | crimson | cyan | fuchsia |
  ghostwhite | gold | goldenrod | gray | green | indigo | ivory | khaki |
  lavender | lime | linen | magenta | maroon | moccasin | navy | olive |
  orange | orchid | peru | pink | plum | purple | red | salmon | sienna |
  silver | snow | tan | teal | thistle | tomato | turquoise |
  violet | white | yellow ;
`, 1);

Sub.component.html
<p>Voice message: {{message}}</p>
    <button [disabled]="started" (click)="start()">Voice start</button>
    <button [disabled]="!started" (click)="stop()">Voice end</button>
<p>lang: en-US</p>


Sub.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SubComponent} from './components';
@NgModule({
  imports: [CommonModule],
  declarations: [SubComponent],
  exports: [SubComponent,],
})
export class SubModule { }


Then copy and paste the codes to demo.component.ts, demo. Component.html and demo.module.ts.

demo.component.ts
import { Component } from '@angular/core';
@Component({
  selector: 'demo-root',
  templateUrl: './demo.component.html',
  styleUrls: ['./demo.component.css'],
})
export class DemoComponent { }


demo.component.html
<test-main></test-main>
<test-sub></test-sub>


Demo.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { DemoComponent } from './demo.component';
import { MainComponent } from './components';
import { SubModule } from '../demo/sub';
import { SpeechRecognitionModule } from '../../projects/ngx-speech-recognition-test/src/public_api';
@NgModule({
  declarations: [
    // app container.
    DemoComponent, MainComponent,
  ],
  imports: [
    BrowserModule,
    CommonModule,
    RouterModule,
    SpeechRecognitionModule.withConfig({
      lang: 'en',
      interimResults: true,
      maxAlternatives: 10,
      // sample handlers.
  onaudiostart:  (ev: Event) => console.log('onaudiostart',ev),
      onsoundstart:  (ev: Event) => console.log('onsoundstart',ev),
      onspeechstart: (ev: Event) => console.log('onspeechstart',ev),
      onspeechend:   (ev: Event) => console.log('onspeechend',ev),
      onsoundend:    (ev: Event) => console.log('onsoundend',ev),
      onaudioend:    (ev: Event) => console.log('onaudioend', ev),
      onresult:      (ev: SpeechRecognitionEvent) => console.log('onresult',ev),
      onnomatch:     (ev: SpeechRecognitionEvent) => console.log('onnomatch',ev),
      onerror:       (ev: SpeechRecognitionError) => console.log('onerror',ev),
      onstart:       (ev: Event) => console.log('onstart', ev),
      onend:         (ev: Event) => console.log('onend',ev),
    }),
    // In SubModule, Component's providers are doing Demo
    // using SpeechRecognitionService generated.
    //
    SubModule,
  ],
  providers: [],
  bootstrap: [DemoComponent]
})
export class DemoModule { }

Added the above codes in the applications. Then please run the applications using ng serve --open or npm start. The application windows http://localhost:4200/ will be opened in the default browser.

If going to run the application first time and click the voice start button browser asks “Use your microphone” permission. If click allows and continues the following steps.

 

After that, I have to click the Voice start button and then speak input words like “hello welcome to angular”. The voice recognition captures them one by one and stores them into the message. Then, give another input into the voice like “I learn typescript”. And click the Voice end button. The whole words into the single lines of message like “hello welcome to angular I learn typescript”.

If you click the voice end button and we have end voice input process has complete sentence will show in the message field. I hope this article is of most helpful for you.



AJAX Hosting - HostForLIFE :: Consuming Web API Using jQuery(AJAX)

clock September 13, 2022 10:28 by author Peter

In this article, we are going to discuss an interesting and useful topic: Consuming Web API using jQuery(AJAX). This method is an easy and quick way to access the web API. We don’t need to write a bunch of code to get access to the API. We will also discuss those errors that are raised at the time of calling an API with jQuery like AddCos and Allow origin. It is normal to get errors like this. I had also faced those errors in early phases.

In this article, I’m going to access my previously created Asp.NET Core API, named Story.com. You can use the one that is required for your desired tasks.

Before we start the steps to consume a Web API, I want to give a brief introduction to both Web API and jQuery AJAX.

Web API
A web API is an Application Programming Interface that is used to access a database in a well-managed way. A web API is an intermediate between a Web application and a database. If we want to access the database in multiple applications, then a Web API is the best way to perform such a task. We don't need to write code again and again to get, post, or update data - we can simply pass the URL and get the response.

jQuery AJAX
In the current context, AJAX is widely used to request data asynchronously from a server. This means that we can send requests to the server without reloading the web page. This is an easy way to interact with the server.

In this article, I will use my previously created API, Story.com, that has a "Get" method.


Here is a Get method that is showing all the data from the database.


This API is attached with the resource file.

To Access a web API with jQuery, we need to follow these steps.

Step 1
In the first step, we are going to create an ASP.Net Core MVC project. I’m using Visual Studio 2022 here. You can use whatever is installed on your machine. So, start Visual Studio and click on create a new project.


Choose Asp.NET Core MVC with Model View Controller and click Next. Then, enter a project name and click create.


Next, we need to enter the Project name.


Step 2
I’m using the default HomeController View. You can add any other controller or view or HTML page to perform this task. Now you need to open the index view, located at View>>Home>>index. cshtml. Now we need to Call the javaScript, located in the wwwRoot folder.


Step 3
First, we call the javascrip.min.js file using @section and Scripts. We’ll write our jQuery within the script tag.
@section Scripts{
    <script>
    </script>
}

Before we move forward to the next step, we need a controller to hold the value of the API. Here I’ve used the table to hold the value of the API. In this table, I only defined the structure of the table. We will define its data rows at run time.
<div class="container">
    <table id="table1" class="table table-dark">
        <tr><th>ID</th><th>Content</th><th>StoryDate</th><th>Author</th><th>Title</th></tr>
    </table>
</div>

In the code above, I created a table with table ID=”table1” and defined their headers.

Note
While creating a table or other control, to bind it using jQuery it must give the ID or name of the control. This is because we will bind data on that control using its Id or its Name.

Step 4
Now, let’s go to our script tag and call a method to load the data from the API. When the document is ready, this means our page is loaded.
$(document).ready(function() {
    GetData();
})


This method calls a method GetData(); when our page is ready.

Step 5
Next, we need to define the functionality to get data from the Web API.
<script>
function GetData() {
    $.ajax({
        url: "https://localhost:7138/api/Story",
        method: "GET",
        success: function(res) {
            var tableString = "";
            $.each(res, function(index, value) {
                tableString += "<tr><td>" + value.iD + "</td><td>" + value.content + "</td><td>" + value.storyStartDate + "</td><td>" + value.auther + "</td><td>" + value.title + "</td></tr>";
            });
            $("#table1").append(tableString);
        },
        error: function(error) {
            console.log(error);
        }
    });
}


Here in this code:
    First we have used the $.ajax() method is used to send the request to the server.
    URL: is used to pass the URL of the Web API here I have the URL of my get API you can use your API URL to get the data from our API.
    method: "GET", here we have to define the method if we are getting the data or we are posting the data. By default, it's set to "GET" data. If you are getting data, then it's not necessary to define, but if we want to post data then it's necessary to define the method as "POST".
    Next,

    success: function(res) {
            var tableString = "";
            $.each(res, function(index, value) {
                tableString += "<tr><td>" + value.iD + "</td><td>" + value.content + "</td><td>" + value.storyStartDate + "</td><td>" + value.auther + "</td><td>" + value.title + "</td></tr>";
            });


In this code we are checking whether the result of the getting method is a success. This means we have gotten the proper or desired response to our request. Then, we need to store the response of the request. So, in the next step, we created a variable with the name tableString to hold the response. To store all these values, we have used $.each loop, which is similar to the for each loop. This loop works dynamically for each element stored in the collection. Here we have stored all data that is coming from the response in the format of table data. Always remember that it is case-sensitive. We have to write the variable names as they are to get the proper value.
Next, we need to append this data into table data. Here we need that controller's Id, in which we want to bind it. In my case, I created a table control to hold the data with the name "table1". This append() will append the data into the table using its id.
$("#table1").append(tableString);

Next, we can also create a method to deal with the errors.
error: function(error) {
    console.log(error);
}


Now if any error occurs when we are getting or loading data from the Web API, we can get the details related to errors in the console. It's not a necessary part; it's optional.

Now, if we run the Program and if your API is live or running, your data will be loaded in the table format.


In this article, we got the data from the ASP.NET Core API using  jQuery AJAX. We can also post or update the data using jQuery AJAX without reloading the page. We just need to pass the desired URL and pass the data with method type "POST", and we can perform the task.



AngularJS Hosting Europe - HostForLIFE :: Angular - Route Guard

clock September 12, 2022 09:14 by author Peter

Introduction
In this article, we are going to discuss an important concept of Angular called Route Guard. We will create a simple angular application to get a better understanding of this concept. This article can be used by beginners, intermediates, and professionals.


I have divided this topic into 3 articles. The below topics will be coved in the first article.
    What is Route Guard?
    Why is it Required?
    Type of Angular Route Guard?
    How to Implement CanActivateGuard?

What is Route Guard?

In the traditional web application, we were checking users' access and permission using Authentication and Authorization on the server side. If the user doesn’t have sufficient access or permission, we were redirecting a user to the login page with an appropriate error message.

Now a question comes to mind; how we will achieve this in Angular? I mean how will restrict a user to access a certain area of the application without login/permission?

That’s one of the scenarios where Route Guard comes into the picture.

Route Guards help us to prevent users to access a certain area of the application that is not permitted or has access to.

Type of Route Guard?
Four types of Route guards are available in Angular. In this article, we will cover the “CanActivate” Route guard and the rest will cover in subsequent articles.
    CanActivate
    CanActivateChild
    CanDeactivate
    CanLoad

Please note that all Route guards have interfaces that need to be implemented in the component class.

eg. “CanActivate” is an interface that has a method called “canActivate”

Please see the below screen to get a better understanding,    

Suppose we have multiple Route guards applied to a specific route then all route guards should return true to navigate. If any route guard returns false then the navigation will be canceled. Let's see below the screen to understand,

In the above screen, we have two route guards,
    MemberAuthGaurd
    DetailsAuthGuard

So both route guards should return true. In case any of the route guards return false then “member” navigation will not work.

Now we will implement “CanActivateGaurd”
How to Implement a CanActivateGuard?

First, we will see the syntax/command used to create a route guard.

Syntax
ng g g “name of the guard”


Now we will create an angular application and implement RouteGuard to get hands-on experience.

Example
In this example, we will
    Create a new angular application,
    Create Two components
    Implement Routing
    Create a new Auth service.
    Create RouteGaurd
    Configure Service in the RouteGuard
    Configure

Please follow the below steps to create the CanActivate Route guard in the Angular application

Step 1 - Create Angular Application.
ng new "routeguarddemo"

Once the application created, we will add two components,

Step 2 - Add two components
ng g c "home"

This command will create HomeComponent. Now let's add another component called “member”
ng g c “member”

Once both components are created. We will configure routing in the next step.

Step 3 - Add routing and create links
Step 3.1

Add the below code in app-routing.module.ts file
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { MemberComponent } from './member/member.component';

const routes: Routes = [

  {path:'home',component:HomeComponent},
  {path:'member',component:MemberComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
export const RoutingComponents =[HomeComponent,MemberComponent];


Step 3.2
Add the below code in app.moule.ts file,
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule, RoutingComponents } from './app-routing.module';
import { Router } from '@angular/router';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
    RoutingComponents
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
 ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


Step 3.3
Add the below code in app.comoponent.html file
<div>
  <a routerLink="/home"  routerLinkActive="active">Home</a>
</div>
<div>
  <a routerLink="/member" routerLinkActive="active">Member</a>
</div>
<router-outlet></router-outlet>


Routing is ready now. Please note that we have not used lazy loading to keep this example simple.

Now we will add Auth service to check user credential and permission.

Step 4 - Add Auth Service and create property called “getUserPermission”
Step 4.1

Execute below command to create service,
ng g s “Auth”

Step 4.2
Add function called get MemberAuth in the service file.

This function should have actual business logic but for demo purpose, I am returning hardcoded “true” or “false” from this function.
import { Injectable } from '@angular/core';
@Injectable({
    providedIn: 'root'
  })
   export class AuthService {

   constructor() { }
   get MemberAuth()
   {
     //Login for Member Auth
     return false;
   }
 }

In the above code, we have created the “MemberAuth” property. In the real world, we will check member authentication and authorization here and return true and false accordingly. But for demo purposes, we are returning hard coded.

Step 5 - Create a RouteGuard
ng g g "memberAuth"

Use the above command to create RouteGuard.

We can create a route guard by selecting any interface but for this example, we will choose the “CanActivate” guard.

New “member-auth.guard.ts “ - RouteGuard file added in the project,
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class MemberAuthGuard implements CanActivate {
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return true;
  }

}

Step 6 - Configure the route guard in the routing file.
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { MemberComponent } from './member/member.component';
import { MemberAuthGuard } from './member-auth.guard';

const routes: Routes = [

  {path:'home',component:HomeComponent},
  {path:'member',component:MemberComponent,canActivate:[MemberAuthGuard]}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
export const RoutingComponents =[HomeComponent,MemberComponent];


In the above code,
    We have added “canActivate:[MemberAuthGuard]” in the route object.
    Imported “MemberAuthGuard” from ‘./member-auth.guard’

Step 7
Call Auth service from route guard to check member access and privileges.
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root'
})
export class MemberAuthGuard implements CanActivate {
  constructor(private _authservice :AuthService)
  {}
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

      if(this._authservice.MemberAuth)
      {
        return true;
      }
      else{
        window.alert("You dont have access!!! Please connect to Administrator ");
        return false;
      }

  }
}


In the above code,
    We have configured “AuthService” in the constructor of MemberAuthGuard.
    Imported Auth service from’./auth.services’
    Called the “MemberAuth” property to check member has access or not. This value comes from Auth Service.
    Alert message in case members don't have access.

Now we will set “false” to return from Auth Service – MemberAuth properly and execute the application.

Output

Member component navigation is not working and getting an error message in the alert. That means that our Route Guard is working fine. You can change AuthSerive – MemberAuth return value to true and check.

I hope, this article has helped you to understand “route guard” and found it useful.



AngularJS Hosting Europe - HostForLIFE :: Building Blocks Of Angular

clock September 8, 2022 10:05 by author Peter

In this article, we are going to see about the building blocks of Angular
    Modules
    Components
    Templates
    Metadata
    Data binding
    Directives
    Services
    Dependency injection

Modules
In angular app has at least one module which we call app module. A module is a container for a group of related components. There are two types of modules one is encapsulating block of function within the single component and the other is encapsulating block of function within a single or group of components by providing exposure in an interface. we need to divide our app module into sub smaller modules and each module is responsible for a specific section.

Components
Its component represents a unique "View" and "View Model" in Model-View-ViewModel (MVVM) pattern or exactly like what components do in Angular. The "View" or Template shows how the complete component will look–when displayed on the browser. "View Model" has all required logic parts to provide "View" with rich functionality and data.

In this case, we followed some steps like below
    Create the Component.
    Register the component in module.
    Add the element in HTML Markup.

Create the Component.

To create the component, we can use the below ng command followed by some name.  
ng generates component component_name

OR

ng g c component_name

Here I have entered the command like ng g c sample. After successfully create component, it will create additionally  
    sample.component.ts (Class with @Component decorator)
    sample.component.html (For the template design)
    sample.component.css (For stylesheets)

Register the component in module
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { SampleComponent } from './sample.component';
@NgModule({
  declarations: [AppComponent,SampleComponent],
  imports: [ BrowserModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


I have registered the component on the appmodule.ts page. We are going to declarations in the samplecomponent.

Add the element in HTML Markup.

Added some markup design in the sample.component.html page like the below code.
<h3>Test Component</h3>

Templates
The templates' view represents a view that improves HTML with Angular functionality like data binding.
import { Component } from '@angular/core';
@Component({
    selector: 'app-root',
    template: '<h2>Test Angular</h2>'
})
export class AppComponent {}


If we want is to encapsulate the data in the container and show it in the template markup dynamically.

In the template to encapsulate the data and when the data changes here at runtime, Angular automatically updates it in the browser view as well.
import { Component } from '@angular/core';
@Component({
    selector: 'app-root',
    template: '<h2> {{ name + "Angular" }}</h2>'
})
export class AppComponent {name = "Test Sat";}


Metadata

Metadata helps in connecting everything in the applications, a "View" with a "View Model" with styles.

    the selector is Metadata in Angular the custom HTML to be included with the component.
    template URL is the exclusive URL for the template to be used when processing the component,
    an array of directives with this kind of Metadata will tell Angular which other Component or the directives should be included in that component.
    an array of style URLs with this type of Metadata you can easily define customized styles for the component.
    Angular how to inject dependencies like services in a component or @RouterConfig that helps you to configure routing in your project application.

Data binding
Data binding is a technique, where the data stays in sync between the component and the view.

There are two different types of data bindings
    one-way  
    two-way binding.

One-way data binding

One-way data binding is a one-way interaction between a component and its HTML template. If you perform any changes in your component, then it will reflect the HTML elements also.
import { Component } from '@angular/core';
@Component({
    selector: 'app-root',
    template: '<h2> {{  name }}</h2>'
})
export class AppComponent {name = "Test Sat";}

Two-way data binding
Two-way data binding is a both-way interaction with components and HTML, data flows in both ways from component to HTML views and HTML views to the component. A simple example is ngModel. If you do any changes in your object model then, it reflects in your HTML view.

Here testdata is one of the objects and another one temptestdata. Initially assign some values in the testdata object and change the value after the user manually enter using passdata click event.
import { Component } from '@angular/core';
@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
     styleUrls: ['./app.component.css']
})
export class AppComponent {
  testdata:string = "Virat Sat";
  temptestdata:String="";
passData(){
    this.temptestdata=testdata;
  }
}


HTML
<input type="text" (ngModel)="testdata">
<button (ngClick)="passData()"> Pass Data Click here </button>
<h3>{{temptestdata}}</h3>


There are three types of Directives present in Angular

Components Directive The component can be used as a directive. Every component has an and Output option to pass between the component and its parent HTML elements.

<selector-name [input-reference]="input-value"> </selector-name>
For Example,
<list-data [items]="datavalues"></list-data>

Structural Directive is like *ngFor and *ngIf which enables you to make changes to DOM with the help of adding or by the Input moving nodes.
<div *ngIf="true">Test Sat data</div>
<li *ngFor="let data of list-data">
  {{ data }}
</li>


Attribute Directive helps in adding behavior or do a change in the look or appearance of a specific element just like ngmodel directive which implements two-way data binding is an Attribute Directive.
<HTMLTag [attrDirective]='value' /></HTMLTag>
For Example,
<p [showToolTip]='Test Virat' />


Services
Services simply help in making reuse of service. As the project becomes bigger naturally more components will add to it and which also will require data to access. So, every time making a copy-paste of code it will create a single reusable singleton data service.

Dependency injection
Dependency Injection to inject the necessary dependencies for a given component/service at runtime and provide flexibility, extensibility, and testability to the framework and your application.

import { Component } from '@angular/core';
import { Service } from './service';
@Component({
    selector: 'app-root',
    template: `
    <ul>
        <li *ngFor="let data of datalist">
            {{ data }}
        </li>
    </ul>
})
export class AppComponent {
    datalist;
    constructor(){
        let service = new Service();
        this.datalist = service.getCourses();
    }
}

We need to explicitly instruct the Angular to create an instance of Service and passes to our AppComponent. This concept is called Dependency Injection. So, we should instruct Angular to inject the dependency of this component into its constructor.

I hope this article was most helpful for you.



AngularJS Hosting Europe - HostForLIFE :: Angular ngx-pagination Sample Implementation Step By Step Guide

clock September 5, 2022 08:41 by author Peter

Angular ngx-pagination Sample Implementation Step By Step Guide
In this example, I will show you how to implement ngx-pagination in your Angular Application.

ngx-pagination is the simplest pagination solution in Angular.

ngx-pagination also offers flexibility, responsiveness, and very handy customization.
I assumed that you have already installed Angular on your local machine. If not then here’s the link to basic Angular Installation.
    FYI: I’m a newbie in Angular I’m just enjoying documenting my journey in learning it.

Step 1: Create Angular Project

Create a new project called ngx-pagination-sample
ng new ngx-paging-sample
    Answer the 2 Angular CLI Questions:
    Would you like to add Angular routing? No
    Which stylesheet format whould you line to use? CSS

After installation, Navigate inside the project folder and open the application.
In my case, I Created a folder in drive: C called Angular and created the ngx-pagination-sample allication inside of it.
C:\Angular>cd ngx-pagination-sample
C:\Angular\ngx-paging-sample>code .


Step 2: Install ngx-pagination
Open Git Bash on your VS Code Terminal, Excecute the following command to add ngx-pagination
ng add ngx-pagination

OR
npm install ngx-pagination

The difference between ng add and npm install ng add, to look for the compatible version to install for your Angular Application while npm install installs the latest version of ngx-pagination which sometimes there are some incompatibility issues especially if you’re using an older version of Angular.

    If you’re using latest Angular Version then use npm install.

Step 3: Install Bootstrap for table and styles
    We need to install the Bootstrap UI package for styling the table and pagination.

Execute the following command:
npm install bootstrap

Go to the angular.json file and look for styles then add the following:
"./node_modules/bootstrap/dist/css/bootstrap.min.css"

Step 4: Setting up Data Model, Service, and Temporary Data
Go to app.module.ts and Import HttClientModule.

This module will help the service to fetch data from a third-party server but in our case, we’re going to use json file for our temporary data.
import { HttpClientModule } from ‘@angular/common/http’;
@NgModule({
    declarations: […],
    imports: [
        HttpClientModule
    ],
    bootstrap: […]
})
export class AppModule {}


Download Temporary Data customers.json then paste it inside your application assets folder.

Create a folder called _models

Inside of _models folder create an interface model called customer.model.ts
export interface Customer {
    id: number;
    firstName: string;
    lastName: string;
    birthday: Date;
    mobileNumber: string;
    email: string;
    createdOn: Date;
}

Inside of _models folder create an interface model called paging-config.model.ts
export interface PagingConfig {
    currentPage: number;
    itemsPerPage: number;
    totalItems: number;
}

Create a folder called _service and inside of it generate a data service called customer, you may create the service manually or type the following:
ng generate service customer

OR
ng g s customer

Add the code in customer.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Customer } from '../_models/customer.model';
@Injectable({
providedIn: 'root'
})
export class CustomerService {
    constructor(private httpClient: HttpClient) {}
    getCustomers(): Observable < Customer[] > {
        return this.httpClient.get < Customer[] > ("assets/customers.json");
    }
}

Step 5: Setting up Angular ngx-pagination
Implement PagingConfig on your AppComponent.ts and add initial values on the properties that will be implemented.

Code in the app.component.ts
import { Component } from '@angular/core';
import { Customer } from './_models/customer.model';
import { PagingConfig } from './_models/paging-config.model';
import { CustomerService } from './_services/customer.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements PagingConfig {
  title = 'ngx-paging-sample';

  currentPage:number  = 1;
  itemsPerPage: number = 5;
  totalItems: number = 0;

  tableSize: number[] = [5, 10, 15, 20];
  customers = new Array<Customer>();

  pagingConfig: PagingConfig = {} as PagingConfig;

  constructor(private customerService: CustomerService){
    this.getCustomers();

    this.pagingConfig = {
      itemsPerPage: this.itemsPerPage,
      currentPage: this.currentPage,
      totalItems: this.totalItems
    }
  }

  getCustomers(){
    this.customerService.getCustomers()
    .subscribe(res=> {
      this.customers = res;
      this.pagingConfig.totalItems = res.length;
    });
  }

  onTableDataChange(event:any){
    this.pagingConfig.currentPage  = event;
    this.getCustomers();
  }
  onTableSizeChange(event:any): void {
    this.pagingConfig.itemsPerPage = event.target.value;
    this.pagingConfig.currentPage = 1;
    this.getCustomers();
  }
}
    pagingConfig property is used for ngx-pagination paginate configuration.
    pagingConfig property will be instantiated inside the AppComponent constructor.

Add the HTML code on your app.component.html
<div class="container">
<div class="row justify-content-between">
  <div class="col-4">
    <h5 class="h3">NGX Pagination</h5>
  </div>
  <div class="col-2">
    <div class="row g-3 align-items-center">
      <div class="col-auto">
      <label class="control-label" for="noOfRows">No. of Rows</label>
    </div>
    <div class="col-auto">
      <select name="noOfRows" (change)="onTableSizeChange($event)" class="form-select form-select-sm">
        <option *ngFor="let size of tableSize" [ngValue]="size">
          {{ size }}
        </option>
      </select>
    </div>
  </div>
</div>
</div>
<br>
<table class="table  table-bordered">
  <thead class="table-dark">
    <tr>
      <th>Id</th>
      <th>Firt Name</th>
      <th>Last Name</th>
      <th>Birth Date</th>
      <th>Mobile Number</th>
      <th>Email</th>
      <th>Registration Date</th>
    </tr>
  </thead>
  <tr *ngFor="let customer of customers | paginate : pagingConfig; let i = index">
    <td>{{ customer.id }}</td>
    <td>{{ customer.firstName }}</td>
    <td>{{ customer.lastName }}</td>
    <td>{{ customer.birthday | date : 'MMMM dd,yyyy' }}</td>
    <td>{{ customer.mobileNumber }}</td>
    <td>{{ customer.email }}</td>
    <td>{{ customer.createdOn | date : 'MM/dd/yyyy' }}</td>
  </tr>
</table>
<div class="d-flex justify-content-center">
  <pagination-controls
  previousLabel="Prev"
  nextLabel="Next"
  (pageChange)="onTableDataChange($event)">
  </pagination-controls>
</div>
</div>


Run the application,
ng serve -o



AngularJS Hosting Europe - HostForLIFE :: How To Use Kendo UI In Angular Application?

clock September 1, 2022 07:26 by author Peter

Preconditions
    Basic knowledge of Angular CLI
    Bootstrap
    Node.js
    V.S. Code

We Covers the belowing things
    Create Angular application
    Create header,side menu and layout component with admin module.
    Angular Routing
    Kendo UI setup

Now let's use following command to create angular project,
ng new KendoUI
cd KendoUI

Now install bootstrap by using the following command,
npm install bootstrap --save

Now install KendoUI packages using following command,
npm install --save @progress/kendo-angular-charts @progress/kendo-angular-common @progress/kendo-angular-intl @progress/kendo-angular-l10n @progress/kendo-angular-popup @progress/kendo-drawing hammerjs @progress/kendo-licensing

Now install KendoUI theme using following command, I used default theme,
Default theme
npm install --save @progress/kendo-theme-default


Bootstrap theme
npm install --save @progress/kendo-theme-bootstrap

Material theme
npm install --save @progress/kendo-theme-material

Now Create the dashboard and layout component using the following command,
ng g c dashboard
ng g c layout

Now add the code in the following pages-:
Add this in app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { GridModule } from '@progress/kendo-angular-grid';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LayoutComponent } from './layout/layout.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { LabelModule } from '@progress/kendo-angular-label';
import { ChartsModule } from '@progress/kendo-angular-charts';
import { ButtonsModule } from '@progress/kendo-angular-buttons';
import { DialogModule } from '@progress/kendo-angular-dialog';
import { UploadModule } from '@progress/kendo-angular-upload';
import { FileSelectModule } from '@progress/kendo-angular-upload';
import { PDFExportModule } from '@progress/kendo-angular-pdf-export';
import { NotificationModule } from '@progress/kendo-angular-notification';
import { NavigationModule } from '@progress/kendo-angular-navigation';
import { IconsModule } from '@progress/kendo-angular-icons';
import { IndicatorsModule } from '@progress/kendo-angular-indicators';
import { LayoutModule } from '@progress/kendo-angular-layout';

@NgModule({
  declarations: [
    AppComponent,
    LayoutComponent,
    DashboardComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    GridModule,
    BrowserAnimationsModule,
    InputsModule,
    LabelModule,
    ChartsModule,
    ButtonsModule,
    DialogModule,
    UploadModule,
    FileSelectModule,
    PDFExportModule,
    NotificationModule,
    NavigationModule,
    IconsModule,
    IndicatorsModule,
    LayoutModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


Add this in app.component.html
<router-outlet></router-outlet>

Add this in app-routing.module.ts
import {
    NgModule
} from '@angular/core';
import {
    RouterModule,
    Routes
} from '@angular/router';
import {
    DashboardComponent
} from './dashboard/dashboard.component';
import {
    LayoutComponent
} from './layout/layout.component';
const routes: Routes = [{
    path: 'Admin',
    component: LayoutComponent,
    children: [{
        path: 'Dashboard',
        component: DashboardComponent
    }]
}, {
    path: '**',
    redirectTo: "/Admin/Dashboard",
    pathMatch: 'full'
}, {
    path: '',
    redirectTo: "/Admin/Dashboard",
    pathMatch: 'full'
}];
@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule {}


Add this in layout.component.ts
import {
    Component,
    OnInit
} from '@angular/core';
@Component({
    selector: 'app-layout',
    templateUrl: './layout.component.html',
    styleUrls: ['./layout.component.css']
})
export class LayoutComponent implements OnInit {
    private data: any;
    public kendokaAvatar = '/assets/img/0.jpg';
    public logout = '/assets/img/logout.png';
    constructor() {}
    ngOnInit(): void {}
    public bottomNavigationItems: Array < any > = [{
        text: 'Home',
        icon: 'home',
        selected: true
    }, {
        text: 'Calendar',
        icon: 'calendar'
    }, {
        text: 'Notifications',
        icon: 'bell'
    }];
}


Add this in layout.component.html
<!--The content below is only a placeholder and can be replaced.-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="">
  <meta name="author" content="">
  <title>Kendo</title>
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<!-- <kendo-breadcrumb [items]="breadCrumbItems"></kendo-breadcrumb> -->
<!-- <kendo-bottomnavigation [border]="true" [items]="bottomNavigationItems"></kendo-bottomnavigation> -->
<br />
  <div id="wrapper">
    <!-- Navigation -->
    <nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
      <!-- <div class="navbar-header"> -->
        <!-- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button> -->
        <!-- <a class="navbar-brand" href="index.html">Kendo Project</a> -->
      <!-- </div> -->
      <!-- /.navbar-header -->
      <!-- /.navbar-top-links -->
      <kendo-appbar position="top">
        <!-- <kendo-appbar-section>
            <button class="k-button k-button-clear">
                <kendo-icon name="menu"></kendo-icon>
            </button>
        </kendo-appbar-section> -->
        <!-- <kendo-appbar-section>
            <h1 class="title">Kendo Project</h1>
        </kendo-appbar-section> -->
        <kendo-appbar-spacer width="32px"></kendo-appbar-spacer>
        <kendo-appbar-section>
            <ul>
                <li><a class="DashFont" [routerLink]="['/Admin/Dashboard']">Dashboard</a></li>
                <!-- <li><a [routerLink]="['/Admin/userlist']">Users</a></li>
                <li><a [routerLink]="['/Admin/profile']">Profile</a></li>
                <li><a [routerLink]="['/Admin/userserver']">User List</a></li> -->
            </ul>
        </kendo-appbar-section>
        <kendo-appbar-spacer></kendo-appbar-spacer>
        <kendo-appbar-section>
          <a [routerLink]="['/Admin/profile']"><kendo-avatar [imageSrc]="kendokaAvatar" shape="circle" width="26px" height="26px"> </kendo-avatar></a>
        </kendo-appbar-section>
        <kendo-appbar-section class="actions">
          <a [routerLink]="['/AdminLogout']"><kendo-avatar [imageSrc]="logout" shape="circle" width="26px" height="26px"> </kendo-avatar></a>
            <kendo-badge-container>
                <button class="k-button k-button-clear">
                    <kendo-icon name="bell"></kendo-icon>
                </button>
                <kendo-badge shape="dot" themeColor="warning" size="small" position="inside"></kendo-badge>
            </kendo-badge-container>
            <span class="k-appbar-separator"></span>
        </kendo-appbar-section>
    </kendo-appbar>
      <!-- <div class="navbar-default sidebar" role="navigation">
        <div class="sidebar-nav navbar-collapse">
          <ul class="nav" id="side-menu">

            <li>
              <a [routerLink]="['/Admin/Dashboard']"><i class="fa fa-edit fa-fw"></i>Dashboard</a>
            </li>
            <li>
              <a [routerLink]="['/Admin/userlist']"><i class="fa fa-edit fa-fw"></i>Users List</a>
            </li>
            <li>
              <a [routerLink]="['/Admin/userserver']"><i class="fa fa-edit fa-fw"></i>Users Server List</a>
            </li>
            <li>
              <a [routerLink]="['/Admin/imagegrid']"><i class="fa fa-edit fa-fw"></i>Image Grid</a>
            </li>
            <li>
              <a [routerLink]="['/AdminLogout']"><i class="fa fa-edit fa-fw"></i>Logout</a>
            </li>
          </ul>
        </div>
      </div> -->
    </nav>
    <div id="page-wrapper">
      <div class="row">
        <div class="col-lg-12">
         <router-outlet></router-outlet>
        </div>
        <!-- /.col-lg-12 -->
      </div>
      <!-- /.row -->
    </div>
  </div>
  <!-- /#page-wrapper -->
  <!-- /#wrapper -->
</body>
</html>

Add this inlayout.component.css
: host {
    padding: 0;
}
kendo - appbar.title {
    font - size: 18 px;
    margin: 10 px;
}
kendo - badge - container {
    margin - right: 8 px;
}
kendo - appbar ul {
    font - size: 14 px;
    list - style - type: none;
    padding: 0;
    margin: 0;
    display: flex;
}
kendo - appbar li {
    margin: 0 9 px;
}
kendo - appbar li: hover {
    cursor: pointer;
    color: #d6002f;
}
kendo - appbar.actions.k - button {
    padding: 0;
}
kendo - breadcrumb {
    margin - left: 30 px;
}.DashFont {
    font - size: 16 px;
    font - family: 'Segoe UI', Tahoma, Geneva, Verdana, sans - serif;
}

Add this in dashboard.component.ts
import {
    Component,
    OnInit
} from '@angular/core';
@Component({
    selector: 'app-dashboard',
    templateUrl: './dashboard.component.html',
    styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
    ngOnInit(): void {}
    constructor() {}
    public events: string[] = [];
    public series: any[] = [{
        name: "India",
        data: [
            3.907, 7.943, 7.848, 9.284, 9.263, 9.801, 3.89, 8.238, 9.552, 6.855,
        ],
    }, {
        name: "Russian Federation",
        data: [4.743, 7.295, 7.175, 6.376, 8.153, 8.535, 5.247, -7.832, 4.3, 4.3],
    }, {
        name: "Germany",
        data: [
            0.01, -0.375, 1.161, 0.684, 3.7, 3.269, 1.083, -5.127, 3.69, 2.995,
        ],
    }, {
        name: "World",
        data: [
            1.988, 2.733, 3.994, 3.464, 4.001, 3.939, 1.333, -2.245, 4.339, 2.727,
        ],
    }, ];
    public categories: number[] = [
        2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
    ];
    public onRender(): void {
        this.log("render");
    }
    public onAxisLabelClick(e: any): void {
        this.log("axisLabelClick", e);
    }
    public onLegendItemClick(e: any): void {
        this.log("legendItemClick", e);
    }
    public onLegendItemHover(e: any): void {
        this.log("legendItemHover", e);
    }
    public onPlotAreaClick(e: any): void {
        this.log("plotAreaClick", e);
    }
    public onPlotAreaHover(e: any): void {
        this.log("plotAreaHover", e);
    }
    public onSeriesClick(e: any): void {
        this.log("seriesClick", e);
    }
    public onSeriesHover(e: any): void {
        this.log("seriesHover", e);
    }
    private log(event: string, arg: any = null): void {
        this.events.push(`${event}`);
        console.log(arg);
    }
    public data: any[] = [{
        kind: 'Hydroelectric',
        share: 0.175
    }, {
        kind: 'Nuclear',
        share: 0.238
    }, {
        kind: 'Coal',
        share: 0.118
    }, {
        kind: 'Solar',
        share: 0.052
    }, {
        kind: 'Wind',
        share: 0.225
    }, {
        kind: 'Other',
        share: 0.192
    }];
    public labelContent(e: any): string {
        return e.category;
    }
}


Add this in dashboard.component.html
<kendo-chart>
    <kendo-chart-title text="Units sold"></kendo-chart-title>
    <kendo-chart-category-axis>
        <kendo-chart-category-axis-item
            [categories]="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'august' , 'september' , 'October', 'november', 'December']"
            [title]="{ text: 'Months' }">
        </kendo-chart-category-axis-item>
    </kendo-chart-category-axis>
    <kendo-chart-series-defaults [highlight]="{ inactiveOpacity: 0.3 }">
    </kendo-chart-series-defaults>
    <kendo-chart-series>
      <kendo-chart-series-item type="area" [data]="[123, 276, 310, 212, 240, 156, 98, 210, 200, 220, 180, 170]">
      </kendo-chart-series-item>
      <kendo-chart-series-item type="area" [data]="[165, 210, 287, 144, 190, 167, 212, 190, 210, 250, 260, 220]">
      </kendo-chart-series-item>
      <kendo-chart-series-item type="area" [data]="[56, 140, 195, 46, 123, 78, 95, 240, 250, 210, 280, 290, 320]">
      </kendo-chart-series-item>
    </kendo-chart-series>
  </kendo-chart>
<hr>
<kendo-chart>
    <kendo-chart-series>
      <kendo-chart-series-item
          type="donut" [data]="data"
          categoryField="kind" field="share">
        <kendo-chart-series-item-labels
          [content]="labelContent"
          color="#fff" background="none">
        </kendo-chart-series-item-labels>
      </kendo-chart-series-item>
    </kendo-chart-series>
    <kendo-chart-legend [visible]="false"></kendo-chart-legend>
  </kendo-chart>

JavaScript

Add this in package.json dependencies

"private": true,
  "dependencies": {
    "@angular/animations": "~12.1.0-",
    "@angular/common": "~12.1.0-",
    "@angular/compiler": "~12.1.0-",
    "@angular/core": "~12.1.0-",
    "@angular/forms": "~12.1.0-",
    "@angular/localize": "~12.1.0-",
    "@angular/platform-browser": "~12.1.0-",
    "@angular/platform-browser-dynamic": "~12.1.0-",
    "@angular/router": "~12.1.0-",
    "@progress/kendo-angular-buttons": "^7.0.0",
    "@progress/kendo-angular-charts": "^6.0.0",
    "@progress/kendo-angular-common": "^2.0.0",
    "@progress/kendo-angular-dateinputs": "^6.0.0",
    "@progress/kendo-angular-dialog": "^6.0.1",
    "@progress/kendo-angular-dropdowns": "^6.0.0",
    "@progress/kendo-angular-excel-export": "^4.0.0",
    "@progress/kendo-angular-grid": "^6.0.1",
    "@progress/kendo-angular-icons": "^1.0.0",
    "@progress/kendo-angular-indicators": "^1.1.2",
    "@progress/kendo-angular-inputs": "^8.0.0",
    "@progress/kendo-angular-intl": "^3.0.0",
    "@progress/kendo-angular-l10n": "^3.0.0",
    "@progress/kendo-angular-label": "^3.0.0",
    "@progress/kendo-angular-layout": "^6.5.0",
    "@progress/kendo-angular-navigation": "^1.1.4",
    "@progress/kendo-angular-notification": "^3.0.4",
    "@progress/kendo-angular-pdf-export": "^3.0.0",
    "@progress/kendo-angular-popup": "^4.0.3",
    "@progress/kendo-angular-progressbar": "^2.0.3",
    "@progress/kendo-angular-treeview": "^6.0.0",
    "@progress/kendo-angular-upload": "^8.0.0",
    "@progress/kendo-data-query": "^1.0.0",
    "@progress/kendo-drawing": "^1.0.0",
    "@progress/kendo-licensing": "^1.0.2",
    "@progress/kendo-svg-icons": "^0.1.2",
    "@progress/kendo-theme-default": "^5.0.0",
    "rxjs": "~6.6.0",
    "tslib": "^2.2.0",
    "zone.js": "~0.11.4"
  },

Now add the attached images

Now run the following command.
npm i

Now, please run the application using the 'npm start' command and check the result.



AngularJS Hosting Europe - HostForLIFE :: Async Validation In Angular

clock August 30, 2022 07:47 by author Peter

In this article, I will explain how to implement Async Validation In Angular. Angular does not provide built-in type async Validation implmentation, it provides only for sync validation. The implementation of async validator is very similar to the sync validator. The only difference is that the async Validators must return the result of the validation as an observable or as Promise. In this article, we will create an async validator for the Existing user. We will check the user exists or not using async validator.

Prerequisites
    Angular 12
    HTML/Bootstrap

For this article, I have created an Angular project using Angular 12. For creating an Angular project, we need to follow the following steps:

Create Project
I have created a project using the following command in the Command Prompt.
ng new AsyncValidatorExample

Open a project in Visual Studio Code using the following commands.
cd AsyncValidatorExample
Code .


Now in Visual Studio, your project looks like as below.


Rules for Async Validator
For creating an Async Validator there are following rules which need to be followed:
    The function must implement the AsyncValidatorFn Interface, which defines the signature of the validator function.
    The function should be returned in following observable or promise.
    If input is valid then must return null, or ValidationErrors if the input is invalid.

AsyncValidatorFn
AsyncValidatorFn is a predefine interface which defines the type of the validator function.

Signature of AsyncValidatorFn
interface AsyncValidatorFn {
  (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>
}

Let's create User Service that will check input user exists or not. For now, we will check it with local parameter not will API call.
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
import { delay } from 'rxjs/operators';

@Injectable({
  providedIn: 'root',
})
export class UserService {
  private usernames = ['Gajendra', 'Rohit', 'Rohan', 'Ajay'];

  checkIfUsernameExists(value: string) {
    return of(this.usernames.some((a) => a.toLocaleUpperCase() === value.toLocaleUpperCase())).pipe(
      delay(1000)
    );
  }
}

Let's create Async Validator to check if the username exists against that method.
import {
  AbstractControl,
  AsyncValidatorFn,
  ValidationErrors,
} from '@angular/forms';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { UserService } from './user.service';

export class UsernameValidator {
  static createValidator(userService: UserService): AsyncValidatorFn {
    return (control: AbstractControl): Observable<ValidationErrors> => {
      return userService
        .checkIfUsernameExists(control.value)
        .pipe(
          map((result: boolean) =>
            result ? { usernameAlreadyExists: true } : null
          )
        );
    };
  }
}


Use Of Async Validator

this.fb.group({
    username: [
      null,
      [UsernameValidator.createValidator(this.userService)],
      updateOn: 'blur'
    ],
  });


App.Component.ts
import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { UserService } from './user.service';
import { UsernameValidator } from './username-validator';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  constructor(private fb: FormBuilder, private userService: UserService) {}

  registrationForm = this.fb.group({
    username: [
      null,{
      asyncValidators:[UsernameValidator.createValidator(this.userService)],
      updateOn: 'blur'
}
    ],
  });
}


App.Component.html
<mat-form-field>
  <mat-label>Username</mat-label>
  <input matInput placeholder="Enter User Name here" formControlName="username" />
  <mat-error
    *ngIf="form.get('username').hasError('usernameAlreadyExists')"
  >
    Username already <strong>exists</strong>
  </mat-error>
</mat-form-field>

Let's Run the Project



European Visual Studio 2022 Hosting - HostForLIFE :: Error - PerfWatson2.exe Issue While Installing SSIS Projects In Visual Studio

clock August 23, 2022 07:07 by author Peter

Got the below error while installing the SQL Server Integration Services Projects for Visual Studio 2019.

Error
Please close following processes before continuing the setup:
PerfWatson2 (17784)

Followed the below steps and resolved the issue.

Step 1
Open the Task Manager and find for PerfWatson2.exe.

Step 2
Right Click on PerfWatson2.exe and Click on End task.


Issue is resolved and continue with the installation process.
Hope you have successfully resolved this issue.
Like and share your valuable feedback on this article.



AngularJS Hosting Europe - HostForLIFE :: Build Custom Audio Player With Audio Waveform In Angular

clock August 19, 2022 10:18 by author Peter

If you are working on a platform that needs to play some audio to a user, for example to sell an audio file, it's awesome to show its wave form. That way, the user will be impressed about the structure of the audio and of what your platform can do. To extract the information from the audio file, Web Audio API can be used. This allows you to extract frequency, waveform and other data from the audio file. Then, the received data from the audio source can be visualized as audio-waves. While dealing with the huge data that an audio waveform will have, drawing waveform smoothly and more quickly without lagging the web page is essential. As a developer, the performance of the page matters a lot, irrespective of the content shown on the page to the developer. So, I'm using CanvasJS chart to visualize the waveform. Note: CanvasJS can draw millions of datapoints in few milliseconds.


This tutorial shows how to create simple MP3 player using web audio API, and how to visualize audio files using CanvasJS. The underlying techniques work within plain JavaScript, Angular, React or any other JavaScript framework. In this case, I'm using Angular to create waveforms.

Browse & Read Audio File
The first step to play audio and visualize waveforms is to get the audio file. Let's add an input field to accept MP3 files. Here I've restricted it to allow the user to browse just MP3 files. However, web audio API supports WAV, MP3, AAC, OGG and other formats.
<input type="file" class="file-input"
       accept="audio/mp3"
       change)="onFileSelected($event)" #fileUpload>


Read Audio File
To fetch audio using the Web Audio API, we need to get an ArrayBuffer of audio data and pass it to a BufferSource. To get an audio buffer of the sound, you need to use the AudioContext.decodeAudioData method. The decoded AudioBuffer is resampled to the AudioContext's sampling rate, then passed to a callback or promise.
let margin = 10,
    chunkSize = 50,
    scaleFactor = (150 - margin * 2) / 2;
let audioContext = new AudioContext(),
    buffer = await file.arrayBuffer(),
    audioBuffer = await audioContext.decodeAudioData(buffer),
    float32Array = audioBuffer.getChannelData(0);
let array = [],
    i = 0,
    length = float32Array.length;
while (i < length) {
    array.push(float32Array.slice(i, i += chunkSize).reduce(function(total, value) {
        return Math.max(total, Math.abs(value));
    }));
}

Add Play / Pause & Stop Buttons
Add two buttons, one for play/pause and another to stop. When the audio is playing, the icon should show what the user can do by clicking that button. So, it will show the "Pause" icon when the audio is playing and "Play" icon when the audio is paused. To do this, we need to toggle between the play and pause states. In Web Audio API, you can check for the state of the audio-context, and based on the current state either resume the audio or suspend it.
togglePlaying = (event: any) => {
    if(audioContext.state === 'running') {
        audioContext.suspend().then(() => {
          buttonStatus = "Play";
        });
    }
    else if(audioContext.state === 'suspended') {
        audioContext.resume().then(() => {
          buttonStatus = "Pause";
        });
    }
}

When it comes to the stop option, this is pretty simple. Web Audio API has option to stop the source by calling stop() method.
stopPlaying = (event: any) => {
    source.stop();
}


Generate Datapoints from the Audio Data
CanvasJS supports varieties of chart types for different sets of data, including line, area, pie, range, and financial charts, etc. For our case, range-area suits well - it looks like audio waves. The only task for us to do is to generate datapoints, pass it to datapoints and call chart.render(). CanvasJS draws wave graphs like a charm.
let dps = []
for (let index in array) {
    dps.push({ x: margin + Number(index), y: [50 - array[index] * scaleFactor, 50 + array[index] * scaleFactor]});
}

this.chart.options.data[0].dataPoints = dps;
this.chart.render();


Add Audio Playing Effect to the Wave

When audio begins playing, it is an excellent idea to shade the region that has already played in the waveform. Add a stripline to show the shaded region in the chart and keep updating it every few milliseconds or second. Stop updating it once the audio stops playing.
source.onended = () => {
    chart.axisX[0].stripLines[0].set("endValue", chart.axisX[0].get("maximum"));
    clearInterval(intervalId);
}
let intervalId = setInterval(() => {
    chart.axisX[0].stripLines[0].set("endValue", audioContext.currentTime * (chart.data[0].dataPoints.length / audioBuffer.duration));
}, 250);


Yippee! You just built a custom audio player with play, pause and stop options, along with the audio waveform generated using CanvasJS range-area chart. You can also use column chart, range-column chart to show waves differently. You can even customize the look and feel of the audio player using simple CSS properties, and can match the same with the waveform by changing CanvasJS chart properties.

This waveform generated by CanvasJS chart can be integrated with an audio/video player to make it more appealing to the user. Library has more customization options to change the look and feel, which gives you more flexibility to customize the chart look and feel to match with your website/player theme. In this tutorial, I have disabled chart interactivity so as to showcase only the waveform. However, CanvasJS supports interactivity where it shows tooltip and highlights when you hover over the chart.



European Visual Studio 2022 Hosting - HostForLIFE :: Automating NuGet Package Uploads

clock August 9, 2022 07:44 by author Peter

The Challenge
When maintaining a larger number of NuGet packages, updating to a new version can become a tedious task. You need to upload all new packages, if there are dependencies between the different packages you also need to be fast in order to avoid breaking your packages. However, this task can also be automated - here's how.

Creating an API key
First of all, you need to create an API key that allows to push new packages to the NuGet server. Once logged in, you can choose the corresponding menu from here:

On the following page you can then choose the key name, the actions available for this key and the packages this key should apply to. In this example, I've used a global pattern to allow uploading all packages starting with combit.ListLabel:


After clicking "Create" you'll have the only chance ever to copy/view the generated key - make sure to use this opportunity wisely. Also, note that keys do have an expiration date. After this, you need to regenerate the key.


Using the Key for Automated Uploads
The next step is to use this key for an automated upload, of course. We've created a rather sophisticated batch file for this purpose which I'm sharing here. All required input is queried from the user. As the owner of this batch file may upload any packages on your behalf, make sure to store it in a very secure path only. The nuget push is repeated for each applicable package at the end.

@ECHO OFF

REM ==================================================================================================================================================
REM CONFIGURATION BEGIN
REM DO NOT EDIT BEFORE THIS LINE!
REM ==================================================================================================================================================
SET MajorVersion=27

SET NuGetExePath=.\nuget.exe

SET ApiKey=<Your API key>
SET Server=https://api.nuget.org/v3/index.json

REM ==================================================================================================================================================
REM CONFIGURATION END
REM DO NOT EDIT AFTER THIS LINE!
REM ==================================================================================================================================================

ECHO INFO: The NuGet version must match the format "Major.Minor.Patch[-Suffix]" (see examples):
ECHO    27.0.0-alpha1
ECHO    27.0.0-beta1
ECHO    27.0.0-beta2
ECHO    27.1.0
ECHO    27.2.1

SET NugetVersionString=%MajorVersion%

:UserPrompt_PrereleaseVersion
ECHO.
SET "UserChoice_PrereleaseVersion="
SET /P "UserChoice_PrereleaseVersion=Enter Pre-release version (values: "alpha" or "beta" without quotes; press 'Enter' to proceed without Pre-release version): %NugetVersionString%.0.0-"

IF /I "%UserChoice_PrereleaseVersion%" == "" (
    GOTO UserPrompt_MinorVersion
) ELSE (
    SET NugetVersionString=%NugetVersionString%.0.0-%UserChoice_PrereleaseVersion%
    GOTO UserPrompt_PrereleaseVersionSuffix
)

:UserPrompt_PrereleaseVersionSuffix
ECHO.
SET "UserChoice_PrereleaseVersionSuffix="
SET /P "UserChoice_PrereleaseVersionSuffix=Enter Pre-release version suffix (values: "2" and higher without quotes; press 'Enter' to proceed with Pre-release suffix default "1"): %NugetVersionString%"

IF /I "%UserChoice_PrereleaseVersionSuffix%" == "" (
    SET NugetVersionString=%NugetVersionString%1
) ELSE (
    SET NugetVersionString=%NugetVersionString%%UserChoice_PrereleaseVersionSuffix%
)

GOTO UserPrompt_FinalWarning

:UserPrompt_MinorVersion
ECHO.
SET "UserChoice_MinorVersion="
SET /P "UserChoice_MinorVersion=Enter Minor version (values: "1" or higher without quotes; press 'Enter' to proceed with default "0"): %NugetVersionString%."

IF /I "%UserChoice_MinorVersion%" == "" (
    SET NugetVersionString=%NugetVersionString%.0
) ELSE (
    SET NugetVersionString=%NugetVersionString%.%UserChoice_MinorVersion%
)

GOTO UserPrompt_PatchVersion

:UserPrompt_PatchVersion
ECHO.
SET "UserChoice_PatchVersion="
SET /P "UserChoice_PatchVersion=Enter Patch version (values: "1" or higher without quotes; press 'Enter' to proceed with default "0"): %NugetVersionString%."

IF /I "%UserChoice_PatchVersion%" == "" (
    SET NugetVersionString=%NugetVersionString%.0
) ELSE (
    SET NugetVersionString=%NugetVersionString%.%UserChoice_PatchVersion%
)

GOTO UserPrompt_FinalWarning

:UserPrompt_FinalWarning
ECHO.
IF /I NOT "%UserChoice_PrereleaseVersion%" == "" (
    SET PackageSourcePath=\\srvchk\prod\LL%MajorVersion%\%UserChoice_PrereleaseVersion%%UserChoice_PrereleaseVersionSuffix%\NuGet
) ELSE (
    SET PackageSourcePath=\\srvchk\prod\LL%MajorVersion%\Release\%MajorVersion%.00%UserChoice_MinorVersion%\NuGet
)

SETLOCAL EnableExtensions EnableDelayedExpansion
SET "UserChoice_FinalWarning=N"
SET /P "UserChoice_FinalWarning=WARNING: This cannot be undone. Really upload NuGet packages for version "%NugetVersionString%" ("%PackageSourcePath%") [Y/N]? "
SET "UserChoice_FinalWarning=!UserChoice_FinalWarning: =!"

IF /I "!UserChoice_FinalWarning!" == "N" ENDLOCAL & GOTO :EOF
IF /I NOT "!UserChoice_FinalWarning!" == "Y" GOTO UserPrompt_FinalWarning

ENDLOCAL
GOTO Upload

:Upload
REM Push packages to server
ECHO.
ECHO Uploading packages...
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.AdhocDesign.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.AdhocDesign.Web.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.CassandraDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.FirebirdConnectionDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.MongoDBDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.MySqlConnectionDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.NpgsqlConnectionDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.NuoDbConnectionDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.OdbcConnectionDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.OleDbConnectionDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.RedisDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.ReportServerIntegration.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.SalesforceDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.SqlConnectionDataProvider.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.Web.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ListLabel%MajorVersion%.Wpf.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ReportServer%MajorVersion%.ClientApi.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%
%NuGetExePath% push "%PackageSourcePath%\combit.ReportServer%MajorVersion%.SharedTypes.%NugetVersionString%.nupkg" -ApiKey %ApiKey% -Source %Server%

PAUSE


The Result
Once executed, the package is uploaded and shows up with the newly created version. The result looks just like a "normal" upload, but the process is much less error prone and executed in a matter of seconds:


Wrapping Up
The presented batch file allows to automate the management of larger NuGet package zoos. We're using it successfully to maintain our roundabout 50 packages with 87k downloads on nuget.org. It will be a great help for others facing the same challenges.



About HostForLIFE

HostForLIFE is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2019 Hosting, ASP.NET 5 Hosting, ASP.NET MVC 6 Hosting and SQL 2019 Hosting.


Tag cloud

Sign in