Full Trust European Hosting

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

Node.js Hosting - HostForLIFE :: Using Express to Create a Node.js API with Swagger Support

clock January 2, 2024 06:50 by author Peter

Overview of Swagger in Node.js
An effective tool for planning, creating, and documenting APIs is Swagger. It gives developers a consistent vocabulary to define RESTful APIs, which facilitates their comprehension, consumption, and interaction with API endpoints. Swagger can be very helpful when producing documentation for Node.js applications that is both machine- and human-readable.

Essential Elements of Swagger
Swagger Specification/OpenAPI: A standard for characterizing RESTful APIs, the Swagger Specification is now the OpenAPI Specification. It establishes a format for machine-readable documentation of the architecture and operation of APIs.

The specification describes parameters, authentication techniques, request/response formats, API endpoints, and more in JSON or YAML.

A user-friendly interface for visualizing and interacting with the Swagger/OpenAPI documentation is called Swagger UI. It enables developers to test endpoints, investigate the API, and comprehend the typical formats for requests and responses.

The Swagger Specification is used to automatically construct the User Interface (UI), which offers an interactive method of interacting with the API.

Swagger Codegen: Based on the Swagger Specification, this tool creates client libraries, server stubs, and API documentation. This can be especially useful for preserving consistency between an API's client and server components.

Integrating Swagger in a Node.js API

To integrate Swagger into a Node.js API, you can follow these step-by-step:
Step 1. Install Necessary Packages

Use npm to install the two required packages, such as express, swagger-jsdoc, and swagger-ui-express.

1. Swagger-jsdoc

npm install swagger-jsdoc --save

2. Swagger-ui-express
npm install swagger-ui-express --save

Go to the project folder and open the terminal to install the required packages.

You can verify whether the package.json package was added or not after installation.

Step 2. Create Swagger Configuration
Write a Swagger configuration file that describes the API using JSDoc comments in the code. This configuration includes information such as API title, version, paths, parameters, and responses.

index.js

const options = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: 'Student Management System',
      version: '1.0.0',
      description: 'Student Management System covered Create, Read, Update, and Delete operations using a Node.js API',
    },
    servers:[
      {url:'http://localhost:5000/api'}, //you can change you server url
    ],
  },

  apis: ['./routes/*.js'], //you can change you swagger path
};

Step 3: Use Swagger Middleware Integration
For your Express.js application, you can use middleware packages such as swagger-jsdoc and swagger-ui-express to integrate Swagger. This middleware serves the Swagger UI and dynamically creates the Swagger Specification.

index.js
1. Import the middleware packages that are needed.

const swaggerUi = require('swagger-ui-express');
const swaggerJsdoc = require('swagger-jsdoc');

JavaScript

2 . Initialize Swagger-jsdoc.

const specs = swaggerJsdoc(options);

JavaScript

3. Serve Swagger documentation using Swagger UI.

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));

JavaScript
Step 4. Define API Routes

Define the API routes using Express.js as usual. Swagger will automatically pick up the route information from the code comments.

Add the Swagger in studentRoute.js

1. API route : router.get("/student", getAllStudents);
Get all students
/**
 * @swagger
 * /student:
 *   get:
 *     summary: Get a list of all students
 *     tags: [Students]
 *     responses:
 *       200:
 *         description: Successful response
 *         content:
 *           application/json:
 *             example:
 *               data: [{}]
 *       400:
 *         description: Bad Request
 *         content:
 *          application/json:
 *            example:
 *             error:
 *              message: "Bad Request"
 */
//Get All Students
router.get("/student", getAllStudents);


2. API route: router.get("/student/:id", getStudent);

Get the Student by ID
/**
 * @swagger
 * /student/{id}:
 *   get:
 *     summary: Get a student by ID
 *     tags: [Students]
 *     parameters:
 *       - name: id
 *         in: path
 *         required: true
 *         description: The ID of the student
 *         schema:
 *           type: string
 *         example:
 *             658918e852a0131af4c0aab1
 *     responses:
 *       200:
 *         description: Successful response
 *         content:
 *           application/json:
 *             example:
 *               data: [{}]
 *       404:
 *         description: Student not found
 */


//Get the Student
router.get("/student/:id", getStudent);


3. API route: router.post("/student", createStudent);
Create a new student
/**
 * @swagger
 * /student:
 *   post:
 *     summary: Create a new student
 *     tags: [Students]
 *     requestBody:
 *       description: Student object to be added
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               name:
 *                 type: string
 *               address:
 *                 type: string
 *               dateOfBirth:
 *                 type: date
 *               gender:
 *                 type: string
 *               phoneNum:
 *                 type: integer
 *             example:
 *                name: "John Doe"
 *                address: "Colombo - Srilanka "
 *                dateOfBirth: 07/14/1990
 *                gender: "male"
 *                phoneNum: 01145252525
 *     responses:
 *       201:
 *         description: Successful response
 *         content:
 *           application/json:
 *             example:
 *               data: [{}]
 *       400:
 *         description: Invalid request
 */


//Create Student
router.post("/student", createStudent);


4. API route: router.put("/student/:id", updateStudent);
Update a student by ID

/**
 * @swagger
 * /student/{id}:
 *   put:
 *     summary: Update a student by ID
 *     description: Update the details of a student by providing the student ID.
 *     tags: [Students]
 *     parameters:
 *       - in: path
 *         name: id
 *         description: The ID of the student to be updated.
 *         required: true
 *         schema:
 *           type: string
 *     requestBody:
 *       description: Updated student information
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               name:
 *                 type: string
 *               address:
 *                 type: string
 *               dateOfBirth:
 *                 type: string
 *                 format: date
 *               gender:
 *                 type: string
 *               phoneNum:
 *                 type: integer
 *     responses:
 *       200:
 *         description: Successful update
 *         content:
 *           application/json:
 *             example:
 *               message: 'Student updated successfully'
 *       404:
 *         description: Student not found
 *         content:
 *           application/json:
 *             example:
 *               message: 'Student not found'
 */


//put the Student
router.put("/student/:id", updateStudent);


5. API route: router.delete("/student/:id", deleteStudent);
Delete a student by ID
/**
 * @swagger
 * /student/{id}:
 *   delete:
 *     summary: Delete a student by ID
 *     tags: [Students]
 *     parameters:
 *       - name: id
 *         in: path
 *         required: true
 *         description: The ID of the student
 *         schema:
 *           type: integer
 *         example:
 *             658918e852a0131af4c0aab1
 *     responses:
 *       204:
 *         description: Student deleted successfully
 *       404:
 *         description: Student not found
 */
//Delete the Student
router.delete("/student/:id", deleteStudent);


Step 5. Run The Application
Start the Node.js application, npm start
Access the Swagger documentation by visiting the specified endpoint, usually /api-docs or a custom path. Example:  http://localhost:5000/api-docs/

Following these steps, you can enhance your Node.js API with interactive and well-documented Swagger/OpenAPI documentation, making it easier for developers to understand, test, and integrate with your API.

1. Go to the swagger path  http://localhost:5000/api-docs/

2. Click on the Try it out button.

3. Click on the Execute button, and get the response.

4. Get the Response.

 

The tutorial walks readers through the process of using Express to create a Node.js API that supports Swagger. To include Swagger into a Node.js API, install the required libraries, make a Swagger configuration file, then use Express.js to define the API routes.

With an emphasis on using Swagger annotations in JSDoc comments to automatically generate interactive Swagger documentation, the book offers thorough code examples for every step. The last section explains how to launch the application and use Swagger UI to view the documentation, which enables developers to easily comprehend, test, and work with the API. The procedures are illustrated clearly in the accompanying photos, which also show how to use the Swagger UI and submit API queries.



AngularJS Hosting Europe - HostForLIFE :: Using Angular CLI 17.0.6, Node: 20.0.1, and npm 10.2.3 on Windows, Create Your First Angular

clock December 19, 2023 06:08 by author Peter

On November 6, 2023, Angular 17 was launched, and I wanted to create my first application with it. These instructions will help you create your first Angular 17 application. With the exception of a few advanced capabilities that must be enabled, this is essentially the same if you have expertise with earlier Angular versions. In addition to a fresh style, Angular 17 introduces several new capabilities for developers and performance. Additionally, Angular17 has well-managed documentation.

Developing an Angular 17 Application
Required conditions

Install the most recent LTS version of NODE JS. I've utilized 20.10.0. Installing and downloading this can be done at https://nodejs.org/en.
During installation, make sure to tick the set Path in the Environment Variables option.

Installing Angular CLI is a required that will be done concurrently with node js installation.
After the installation is complete, use CMD to verify the installed version of the node.

Enter "node -v" in the command window. This screen grab below displays the version that I have installed.

After Node js has been successfully installed, Typescript needs to be installed. Try using the admin version of cmd. Given that folder rights were restricted, I knew I had to take this action. I've included some instructions below in case you're operating through a proxy.

CMD "npm install –g typescript" should be run.

if any of the following mistakes happen. CERT_IN_CHAIN_SELF SIGNED.

I got around the certificate, which is the above error, with this cmd. "npm config set strict-ssl false" Strict SSL configuration will now be set to false. If the installation goes well, it will seem like the screen below, which indicates that the installation was successful.

Run the command "npm install -g @angular/cli@latest" as shown above the screen. It does say about funding which is to ask for funds.
Some of these packages installed are probably asking for funds. (optional)

You can check the version installed using the command "ng version"

Now that the prerequisites have been met, use the command "ng new {APPName}" to begin building a new Angular17 application. The CLI will inquire about the type of styling you want to use and whether you need to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering) when you create a new application.

When user interaction with the backend is required, server-side rendering is employed.

To launch the ng serve –o application, use this command. Your browser will launch it at http://localhost:4200/.


Thank you, and Hopefully, this article helped you get started with creating an angular 17 application.



AngularJS Hosting Europe - HostForLIFE :: In an Angular Application, Create a Custom Search Filter Pipeline

clock December 13, 2023 06:14 by author Peter

This post will teach us how to use an Angular application to design a custom search filter pipe.


Required conditions

Basic familiarity with Angular 2 or later; installation of Node and NPM; Visual Studio Code; Bootstrap (Optional)
The command to create an Angular project is as follows.
ng new angapp

Now install Bootstrap by using the following command.
npm install bootstrap --save

Now open the styles.css file and add Bootstrap file reference. To add a reference in the styles.css file add this line.
@import '~bootstrap/dist/css/bootstrap.min.css';

Create Search Filter Pipe
Now create a custom pipe by using the following command.
ng generate pipe searchfilter

Now open searchfilter.pipe.ts file and add following code.
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'searchFilter' })
export class FilterPipe implements PipeTransform {
   transform(value: any, args?: any): any {
    if (!value) return null;
    if (!args) return value;

    args = args.toLowerCase();
    debugger;
    return value.filter(function(item:any) {
      return JSON.stringify(item)
        .toLowerCase()
        .includes(args);
    });
  }
}

Now import this pipe into the app module.Add following code in app.module.ts.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FilterPipe } from './searchfilter.pipe';
import { SearchlistComponent } from './searchlist/searchlist.component';
@NgModule({
  declarations: [
    AppComponent,FilterPipe,SearchlistComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


Now create a new component by using the following command.
ng g c searchlist

Now open searchlist.component.html file and add the following code.
<div class="container">
    <div class="card">
        <div class="form-group">
            <label for="search-text">Search Text</label>
            <input type="email" class="form-control" id="search-text" aria-describedby="search-text"
                [(ngModel)]="searchText" placeholder="Enter text to search" autofocus>
        </div>
        <ul class="list-group list-group-flush">
            <li class="list-group-item" *ngFor="let user of userlist | searchFilter: searchText">
                {{user.firstName}}
            </li>
        </ul>
    </div>
</div>

Now open searchlist.component.ts file and add the following code.
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
  selector: 'app-searchlist',
  templateUrl: './searchlist.component.html',
  styleUrls: ['./searchlist.component.css']
})
export class SearchlistComponent implements OnInit {
  data: any;
  searchText = '';
  userlist: any;
  constructor(private httpclient: HttpClient) {
  }
  ngOnInit(): void {
    this.httpclient.get('https://dummyjson.com/users').subscribe((res: any) => {
      this.data = res
      this.userlist = this.data.users;
      console.log(this.userlist);
    })
  }
}


Now open app.component.html file and add the following code.
<div class="container" style="margin-top:10px;margin-bottom: 24px;">
  <div class="col-sm-12 btn btn-info">
    Create Custom Search filter pipe in Angular Application
  </div>
</div>
<app-searchlist></app-searchlist>


Now run the application using npm start and check the result.

Now type some text into the box and run a search.




AngularJS Hosting Europe - HostForLIFE :: Essentials of Dependency Injection in Angular

clock December 8, 2023 08:06 by author Peter

Dependency Injection (DI) is a powerful front-end framework developed by Google that makes it easy to manage services and components inside an application. Dependencies can be received by components instead of being created directly thanks to DI, a design paradigm that encourages loose coupling. In order to better understand DI in Angular, this post will go through its core ideas, benefits, and real-world application using code samples.

Injecting Dependency in Angular
A software design technique called dependency injection makes it possible to create easily maintained, loosely linked components. DI is a method used with Angular that allows a component to obtain its dependencies from outside sources instead of generating them on its own. The Angular Injector, which is in charge of instantiating and maintaining the dependencies of different components, is usually this external source.

Dependency Injection's Advantages in Angular

  • Loose Coupling: DI encourages loose coupling, which makes it simpler to update or replace dependencies without impacting the whole program.
  • Testability: Dependencies can be easily injected to mock or test during unit testing, making DI-patterned components more testable.
  • Reusability: DI makes services and components more reusable because it makes it simple to inject them into various application sections without requiring any changes.
  • Maintainability: The codebase is more maintainable because to the concern separation made possible by DI. It is less probable for changes made to one section of the application to affect other sections.

How Dependency Injection Operates in Angular?
The Angular Injector is used in Angular to construct the DI system. In order to control the scope of dependencies, the Injector upholds a hierarchical structure while generating instances of components, services, and other objects.

Here's a quick example to help you grasp how DI functions in Angular. Think about a service known as DataService.

// data.service.ts

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})

export class DataService {
  getData(): string {
    return 'This is data from the DataService';
  }
}

To indicate that the DataService in this example is a service that may be injected into other components or services, the @Injectable decorator is used. Throughout the application, there will only be one instance of DataService thanks to the providedIn: 'root' setting.

Let's use this service to create an AppComponent component now.

// app.component.ts

import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-root',
  template: '<h1>{{ data }}</h1>',
})

export class AppComponent {
  data: string;
  constructor(private dataService: DataService) {
    this.data = this.dataService.getData();
  }
}


In this example, the AppComponent class has a constructor that takes an instance of DataService as a parameter. The Angular Injector automatically injects the appropriate instance when creating an AppComponent.

import { Component, Injector } from '@angular/core';
import { DataService } from './data.service';

@Component({

  selector: 'app-root',
  template: '<h1>{{ data }}</h1>',

})

export class AppComponent {
  data: string;
  constructor(private injector: Injector) {
    const dataService = this.injector.get(DataService);
    this.data = dataService.getData();
  }
}


In this example, we inject the Injector itself and then use it to manually get an instance of the DataService. While manual injection is rarely needed, it provides a way to have more control over the injection process.

In summary
A key idea in Angular that enhances the framework's adaptability, testability, and maintainability is dependency injection. You may build scalable and modular Angular applications by comprehending DI and applying it into your application architecture. The hierarchical structure enables for fine-tuning the scope of dependencies, while the automatic injection offered by the Angular Injector makes dependency management easier.

Adopting and understanding Dependency Injection will definitely improve the overall architecture and code quality as you continue to develop Angular applications.



AngularJS Hosting Europe - HostForLIFE :: Angular CLI: Your Angular Development Shortcut

clock November 30, 2023 06:28 by author Peter

Introduction
As a strong and extensively used framework for creating dynamic online apps, Angular reigns supreme in the world of front-end development. Google released the Angular Command Line Interface (CLI) to help developers on their Angular journey, a versatile tool that accelerates the development process, automates common operations, and improves code maintainability.


Explore Angular CLI by delving into its fundamental functionality and important commands that make Angular programming a breeze. The Angular CLI, a command-line tool, makes it easier to create, build, test, and deploy Angular apps. It shields developers from the complexity of extensive configurations, allowing them to focus on developing code rather than setup and boilerplate code.

Installation
Before you begin your Angular CLI adventure, make sure your workstation has the most recent version installed globally.

npm install -g @angular/cli

Project Creation
With Angular CLI, project creation is a breeze. A single command conjures the necessary files and folder structures, laying the groundwork for your project:
ng new my-angular-project

This command guides you through various configuration options, including Angular routing integration and stylesheet preferences (CSS, SCSS, etc.).
Generating Components, Services, and Beyond

Angular CLI provides generators for various application components, automatically scaffolding the files required for each feature. For instance, to generate a new component:
ng generate component my-new-component

This command produces the necessary files for a component, including the component class, template, and styles.

Running the Application
Once your application is set up, you can use the following command to launch it locally:
ng serve

This command kicks off a development server, allowing you to view your application in all its glory by navigating to http://localhost:4200 in your web browser.

Building for Production
When the time comes to unleash your application upon the world, Angular CLI simplifies the deployment process. The following command transforms your application for production, optimizing the code for peak performance:
ng build

The compiled and minified files are neatly organized in the dist/ directory, ready to be deployed to a web server.

Running Tests
Angular CLI seamlessly integrates testing into the development workflow. The following command executes unit tests.
ng test

These commands safeguard your application's quality and functionality throughout the development process.
ng add

The ng add command simplifies the process of incorporating new libraries or features into your Angular project. For instance, to add Angular Material to your project.
ng add @angular/material

This automatically installs the necessary dependencies and updates your project configuration.
ng update

Angular CLI makes it a breeze to keep your project up-to-date with the latest Angular versions and dependencies. The following command refreshes your Angular dependencies.
ng update @angular/cli

This ensures that your project benefits from the latest features, bug fixes, and security updates.

Conclusion
Angular CLI is a cornerstone of the Angular development ecosystem, providing developers with a robust set of tools to help them streamline their workflow. The CLI commands covered here are only a sampling of its extensive capabilities, demonstrating the convenience and simplicity that Angular CLI adds to the development process.

Angular CLI allows developers to focus on building strong and feature-rich apps rather than getting bogged down by tedious setups when creating new projects, producing components, running tests, or optimizing for production. Accept Angular CLI and see your Angular development journey convert into a simple and productive one.



European Visual Studio Hosting - HostForLIFE :: Visual Studio 17.8: Improving Developer Experience

clock November 22, 2023 06:50 by author Peter

Staying ahead of the curve in the ever-changing world of software development is more than a goal—it's a requirement. Microsoft's latest Visual Studio 2022 release, version 17.8, is a big step forward in this path. As an outside observer and voice in the technology industry, I've seen Visual Studio evolve over the years, and this release is especially important.


Visual Studio 17.8 is a tribute to Microsoft's commitment to innovation and community feedback, since it is jam-packed with improvements that address developers' real-world demands. It is more than just an upgrade; it is a reinvention of what a development environment may be. This version, which is completely compatible with.NET 8, includes a mix of productivity upgrades, language advancements, and enterprise capabilities.

Let's take a look at what makes Visual Studio 17.8 such a game changer for developers of all disciplines and ability levels.

Visual Studio 17.8 will take you to new heights
Microsoft's Visual Studio 2022 has reached a new milestone with version 17.8. This upgrade is more than just a step forward; it is a leap into the future of development. It incorporates the best community feedback and ushers in complete compatibility with.NET 8, which is now widely accessible.

What Is the Latest in Productivity?

  • GitHub Copilot: With AI-powered support, this innovative addition to Visual Studio speeds coding. It's like having a co-pilot for your coding journey, speeding up and simplifying the process.
  • Create a Pull Request: You may now easily create a Pull Request directly from Visual Studio. This feature, which was strongly requested by the community, demonstrates Microsoft's dedication to user-driven innovations.
  • Improved Multi-Repo Support: Managing several repositories? The maximum has now been raised to 25, making multitasking easier than ever.
  • Summary Diff has been improved to provide a more efficient manner of reviewing changes, focusing on what is most important in your commits.
  • Remote Linux Unit Test Support: This capability enables testing to be seamlessly integrated across platforms.

Your Opinion Is Important
This release is notable not only for its features, but also for its focus on community-driven improvements. Microsoft exhibits its dedication to user feedback by incorporating top-ranked enhancements based on consumer votes.

Try it out and let us know what you think

Microsoft welcomes your comments as you explore these new features. Your feedback will be crucial in influencing future improvements and ensuring Visual Studio's position as a premier development tool.



Node.js Hosting - HostForLIFE :: How Do I Fix Nodemon Command Is Not Recognized In Node.js Terminal?

clock November 9, 2023 07:53 by author Peter

We will look at two key features of working with Node.js and Nodemon in this article. First, we'll walk you through the process of installing Nodemon, a critical tool for developers aiming to speed up the development of Node.js apps. By understanding how to install Nodemon, you can use its power to automatically restart your server anytime code changes. You will save time and effort as a result of this.


The "Nodemon command is not recognized" terminal error is a common and vexing issue for developers. We'll investigate the core causes of this problem and provide you with a clear, step-by-step plan for resolving it. Whether you're a seasoned Node.js developer or just getting started, mastering these core skills will result in a more efficient and successful development process.

node -v

Step 2. Open Your Terminal
To install Nodemon globally, use the following command.
npm install -g nodemon

Step 3. Verify Installation

You can use the next command to verify that Nodemon has been correctly installed.
nodemon -v


How to fix the nodemon command that is not recognized in the terminal for Node.js?

The "Nodemon command is not recognized" error can be annoying, but have no worry — it's a common problem with a simple fix. In this section, we'll walk you through the procedures to fix the issue and set up Nodemon on your machine.

Step 1. Install npm
To install npm, use the following command.
npm install

Step 2. Update package.json file
To update package.json, use the following scripts.
"scripts": {
    "server": "nodemon index.js"
  },


Step 3. Run project
To run the project, use the following commands.
npm run server

Conclusion
Installing Nodemon and fixing the typical "Nodemon command is not recognized" problem are two essential components of Node.js development that have been covered in this article. Nodemon is a useful tool for streamlining development efficiency by automatic server restarts following code changes. To ensure you can exploit Nodemon's features to the fullest, the "How to Install Nodemon in Node.js" section offers a detailed tutorial. The section titled "How to Fix Nodemon Command Is Not Recognized in the Terminal for Node.js" also addresses the annoying "Nodemon command is not recognized" error and offers workable alternatives. With these tips, your Node.js development process will go more smoothly and effectively, allowing you to concentrate on writing code while Nodemon takes care of the rest.



AngularJS Hosting Europe - HostForLIFE :: Angular State Management Pattern

clock November 6, 2023 08:07 by author Peter

In Angular, the State Management pattern is critical for managing complicated application states. NgRx (Redux-inspired), Akita, and Ngxs are some of the most popular state management libraries. Here's an example of how to use NgRx in Angular for state management:
NgRx should be installed.


To install NgRx, open your Angular project in a terminal and perform the following command:

Define your Actions
To define the activities that can be dispatched, create action files. Create a file called user.actions.ts with the following code:

import { createAction, props } from '@ngrx/store';
import { User } from './user.model';
export const loadUsers = createAction('[User] Load Users');
export const loadUsersSuccess = createAction('[User] Load Users Success', props<{ users: User[] }>());
export const loadUsersFailure = createAction('[User] Load Users Failure', props<{ error: string }>());

Make Reducers
Create reducer files to specify how the state changes as a result of actions. Create a file called user.reducer.ts with the following code:

import { createReducer, on } from '@ngrx/store';
import { User } from './user.model';
import * as UserActions from './user.actions';
export interface UserState {
  users: User[];
  loading: boolean;
  error: string | null;
}
const initialState: UserState = {
  users: [],
  loading: false,
  error: null,
};
export const userReducer = createReducer(
  initialState,
  on(UserActions.loadUsers, (state) => ({ ...state, loading: true, error: null })),
  on(UserActions.loadUsersSuccess, (state, { users }) => ({ ...state, users, loading: false })),
  on(UserActions.loadUsersFailure, (state, { error }) => ({ ...state, loading: false, error }))
);

Define Selectors
Create selector files to extract specific data from the state. For example, create a file named user.selectors.ts with the following code:

import { createFeatureSelector, createSelector } from '@ngrx/store';
import { UserState } from './user.reducer';
export const selectUserState = createFeatureSelector<UserState>('user');
export const selectUsers = createSelector(selectUserState, (state) => state.users);
export const selectLoading = createSelector(selectUserState, (state) => state.loading);
export const selectError = createSelector(selectUserState, (state) => state.error);

Use NgRx in a Component

Create a component that utilizes NgRx for state management. For example, create a file named user.component.ts with the following code:
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { User } from './user.model';
import * as UserActions from './user.actions';
import { selectUsers, selectLoading, selectError } from './user.selectors';
@Component({
  selector: 'app-user',
  template: `
    <h2>User Component</h2>
    <div *ngIf="loading">Loading...</div>
    <div *ngIf="error">{{ error }}</div>
    <ul>
      <li *ngFor="let user of users">{{ user.name }}</li>
    </ul>
  `,
})
export class UserComponent implements OnInit {
  users$: Observable<User[]>;
  loading$: Observable<boolean>;
  error$: Observable<string>;
  constructor(private store: Store) {}
  ngOnInit(): void {
    this.users$ = this.store.select(selectUsers);
    this.loading$ = this.store.select(selectLoading);
    this.error$ = this.store.select(selectError);
    this.store.dispatch(UserActions.loadUsers());
  }
}

Build and run the application: Use the following command to build and serve the Angular application:

ng serve
Your application will be accessible at http://localhost:4200.

In this example, NgRx is used for state management. Actions are dispatched to trigger state changes, reducers define how the state changes, and selectors are used to extract specific data from the state. The UserComponent subscribes to the state using NgRx's select method and displays the data in the template.

By following the State Management pattern with NgRx or other state management libraries, you can centralize and manage complex application states efficiently, leading to better code organization, maintainability, and scalability.



AngularJS Hosting Europe - HostForLIFE :: Data Transfer Without Parent and Child Component

clock November 2, 2023 07:58 by author Peter

Hello, my friend. I am thrilled to present my debut article.
How can we transfer data from one component to another via service?


Create a service file first.
command- ng g s <service_name>

Step 2. To share data on the click of a button.
<button (click)="sendDataToReceiver()">Send Data</button>

Step 3. Import service in the ts file.
private dataService: DataService

Step 4. Method call.
this.yourServicename.sendData("Hello from Sender");

Step 5. Import your service to send data and get Data.
private dataSubject = new Subject<string>();

sendData(data: string) {
  this.dataSubject.next(data);
}

getData() {
  return this.dataSubject.asObservable();
}

Step 6. Finally, get Data from the Service.
Import your service and create a variable.
ngOnInit() {
  this.serviceName.getData().subscribe(data => {
    this.receivedData = data;
  });
}



AngularJS Hosting Europe - HostForLIFE :: Simply Record an Audio File in Angular 16 and Save it as a WAV File

clock October 23, 2023 08:02 by author Peter

WAV stands for "Waveform Audio File Format." It is the industry standard for storing an audio bitstream on a computer. The WAV format, created by IBM and Microsoft, is based on the Resource Interchange File Format (RIFF) and is extensively used for storing uncompressed audio data on Windows PCs. WAV files retain great quality and might be big since they contain extensive audio information.


You can utilize the native "MediaRecorder" in an Angular application to record audio from a microphone.

The Web API's "MediaRecorder" interface allows you to effortlessly record media. It is intended to record audio or video directly from the browser, making media stream capture easier.

MediaRecorder's main features and capabilities are as follows:

It is possible to record audio and video streams directly from the user's camera and microphone using Media Capture.

Stream Recording: It records media streams in segments that can be separately processed or saved.

Different Media Formats: Depending on the browser and system, it supports a variety of audio and video formats.

It provides multiple event handlers, such as ondataavailable, onstart, onstop, onerror, and others, to handle various elements of recording.

Configurable: You can customize the MediaRecorder by changing settings such as the MIME type of the recording, the bit rate, and so on.

Although "MediaRecorder" is commonly supported in recent browsers, the precise codecs and formats supported may differ between browsers. It is always a good idea to test the browser's compatibility and capabilities at runtime.

The "MediaRecorder" interface makes it easier to record audio and video in online applications, giving developers a powerful tool for capturing and working with media streams directly in the browser.

MediaRecorder takes audio in webm format by default. You must convert the recorded audio buffer to WAV format if you want a genuine WAV file rather than a webm file with a.wav extension. 

Using the Angular CLI (Command Line Interface), create an Angular 16 application.

To create a new Angular application, use the command below.  

Adding a New AudioRecorder
We can proceed by selecting the default Routing and Styling choices.  

Make a class to convert an audio buffer to WAV format.

audio-helper.ts

export function bufferToWave(abuffer:any, len:number) {
    let numOfChan = abuffer.numberOfChannels,
      length = len * numOfChan * 2 + 44,
      buffer = new ArrayBuffer(length),
      view = new DataView(buffer),
      channels = [],
      i, sample,
      offset = 0,
      pos = 0;

    // write WAVE header
    setUint32(0x46464952);                         // "RIFF"
    setUint32(length - 8);                         // file length - 8
    setUint32(0x45564157);                         // "WAVE"

    setUint32(0x20746d66);                         // "fmt " chunk
    setUint32(16);                                 // length = 16
    setUint16(1);                                  // PCM (uncompressed)
    setUint16(numOfChan);
    setUint32(abuffer.sampleRate);
    setUint32(abuffer.sampleRate * 2 * numOfChan); // avg. bytes/sec
    setUint16(numOfChan * 2);                      // block-align
    setUint16(16);                                 // 16-bit (hardcoded in this demo)

    setUint32(0x61746164);                         // "data" - chunk
    setUint32(length - pos - 8);                   // chunk length

    // write interleaved data
    for (i = 0; i < abuffer.numberOfChannels; i++)
      channels.push(abuffer.getChannelData(i));

    while (pos < length) {
      for (i = 0; i < numOfChan; i++) {             // interleave channels
        sample = Math.max(-1, Math.min(1, channels[i][offset])); // clamp
        sample = (0.5 + sample < 0 ? sample * 32768 : sample * 32767)|0; // scale to 16-bit signed int
        view.setInt16(pos, sample, true);          // write 16-bit sample
        pos += 2;
      }
      offset++                                     // next source sample
    }

    // create Blob
    return new Blob([buffer], { type: "audio/wav" });

    function setUint16(data:any) {
      view.setUint16(pos, data, true);
      pos += 2;
    }

    function setUint32(data:any) {
      view.setUint32(pos, data, true);
      pos += 4;
    }
  }

We can create an Audio Recording service and integrate the helper function in the service.
ng g s AudioRecording

audio-recording-service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { bufferToWave } from './audio-helper';

@Injectable({
  providedIn: 'root'
})
export class AudioRecordingService {
  private chunks: any[] = [];
  private mediaRecorder: any;
  private audioContext: AudioContext = new AudioContext();
  private audioBlobSubject = new Subject<Blob>();

  audioBlob$ = this.audioBlobSubject.asObservable();

  async startRecording() {
    if (this.audioContext.state === 'suspended') {
      await this.audioContext.resume();
    }

    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    this.mediaRecorder = new MediaRecorder(stream);
    this.mediaRecorder.ondataavailable = (event: any) => this.chunks.push(event.data);
    this.mediaRecorder.start();
  }

  async stopRecording() {
    if (this.mediaRecorder) {
      this.mediaRecorder.onstop = async () => {
        const audioData = await new Blob(this.chunks).arrayBuffer();
        const audioBuffer = await this.audioContext.decodeAudioData(audioData);
        const wavBlob = bufferToWave(audioBuffer, audioBuffer.length);
        this.audioBlobSubject.next(wavBlob);
        this.chunks = [];
      };

      this.mediaRecorder.stop();
    }
  }
}

Update the component html file with code below.  

app.component.html

<div class="content" role="main">

  <div class="row justify-content-center pt-2 pb-2">
    <button title="Click here to start recording action" class="btn-mic w-auto" (click)="startRecording()"
      *ngIf="!isRecording" style="margin-right: 3px;">
      <img src="../../assets/mic.png" />
    </button>
    <button title="Click here to stop recording" class="btn-stop w-auto" (click)="stopRecording()" *ngIf="isRecording"
      style="margin-right: 3px;">
      <img src="../../assets/stop.png" />
    </button>
  </div>
  <audio #audioPlayer controls style="margin: 10px;"></audio>
  <a *ngIf="audioURL" [href]="audioURL" download="recorded_audio.wav">Download last reecorded Audio</a>
</div>

Update the component class file with code below.

app.component.ts
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { AudioRecordingService } from './audio-recording.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  isRecording = false;
  audioURL: string | null = null;
  @ViewChild('audioPlayer') audioPlayer!: ElementRef<HTMLAudioElement>;

  constructor(private audioRecordingService: AudioRecordingService, private cd: ChangeDetectorRef) { }

  ngOnInit() {
    this.audioRecordingService.audioBlob$.subscribe(blob => {
      this.audioURL = window.URL.createObjectURL(blob);
      this.audioPlayer.nativeElement.src = this.audioURL;
      this.cd.detectChanges();
    });
  }

  startRecording() {
    this.isRecording = true;
    this.audioRecordingService.startRecording();
  }

  stopRecording() {
    this.isRecording = false;
    this.audioRecordingService.stopRecording();
  }
}

Update the component stylesheet with code below.

app.component.css

:host {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    font-size: 14px;
    color: #333;
    box-sizing: border-box;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    margin: 8px 0;
}

p {
    margin: 0;
}

.spacer {
    flex: 1;
}

.toolbar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 60px;
    display: flex;
    align-items: center;
    background-color: #1976d2;
    color: white;
    font-weight: 600;
}

.toolbar img {
    margin: 0 16px;
}

.toolbar #twitter-logo {
    height: 40px;
    margin: 0 8px;
}

.toolbar #youtube-logo {
    height: 40px;
    margin: 0 16px;
}

.toolbar #twitter-logo:hover,
.toolbar #youtube-logo:hover {
    opacity: 0.8;
}

.content {
    display: flex;
    margin: 10px auto 10px;
    padding: 0 16px;
    max-width: 960px;
    flex-direction: column;
    align-items: center;
}

svg.material-icons {
    height: 24px;
    width: auto;
}

svg.material-icons:not(:last-child) {
    margin-right: 8px;
}

.card svg.material-icons path {
    fill: #888;
}

.card-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    margin-top: 16px;
}

.card {
    all: unset;
    border-radius: 4px;
    border: 1px solid #eee;
    background-color: #fafafa;
    height: 40px;
    width: 200px;
    margin: 0 8px 16px;
    padding: 16px;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    transition: all 0.2s ease-in-out;
    line-height: 24px;
}

.card-container .card:not(:last-child) {
    margin-right: 0;
}

.card.card-small {
    height: 16px;
    width: 168px;
}

.card-container .card:not(.highlight-card) {
    cursor: pointer;
}

.card-container .card:not(.highlight-card):hover {
    transform: translateY(-3px);
    box-shadow: 0 4px 17px rgba(0, 0, 0, 0.35);
}

.card-container .card:not(.highlight-card):hover .material-icons path {
    fill: rgb(105, 103, 103);
}

.card.highlight-card {
    background-color: #1976d2;
    color: white;
    font-weight: 600;
    border: none;
    width: auto;
    min-width: 30%;
    position: relative;
}

.card.card.highlight-card span {
    margin-left: 60px;
}

svg#rocket {
    width: 80px;
    position: absolute;
    left: -10px;
    top: -24px;
}

svg#rocket-smoke {
    height: calc(100vh - 95px);
    position: absolute;
    top: 10px;
    right: 180px;
    z-index: -10;
}

a,
a:visited,
a:hover {
    color: #1976d2;
    text-decoration: none;
}

a:hover {
    color: #125699;
}

.terminal {
    position: relative;
    width: 80%;
    max-width: 600px;
    border-radius: 6px;
    padding-top: 45px;
    margin-top: 8px;
    overflow: hidden;
    background-color: rgb(15, 15, 16);
}

.terminal::before {
    content: "\2022 \2022 \2022";
    position: absolute;
    top: 0;
    left: 0;
    height: 4px;
    background: rgb(58, 58, 58);
    color: #c2c3c4;
    width: 100%;
    font-size: 2rem;
    line-height: 0;
    padding: 14px 0;
    text-indent: 4px;
}

.terminal pre {
    font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
    color: white;
    padding: 0 1rem 1rem;
    margin: 0;
}

.circle-link {
    height: 40px;
    width: 40px;
    border-radius: 40px;
    margin: 8px;
    background-color: white;
    border: 1px solid #eeeeee;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
    transition: 1s ease-out;
}

.circle-link:hover {
    transform: translateY(-0.25rem);
    box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2);
}

footer {
    margin-top: 8px;
    display: flex;
    align-items: center;
    line-height: 20px;
}

footer a {
    display: flex;
    align-items: center;
}

.github-star-badge {
    color: #24292e;
    display: flex;
    align-items: center;
    font-size: 12px;
    padding: 3px 10px;
    border: 1px solid rgba(27, 31, 35, .2);
    border-radius: 3px;
    background-image: linear-gradient(-180deg, #fafbfc, #eff3f6 90%);
    margin-left: 4px;
    font-weight: 600;
}

.github-star-badge:hover {
    background-image: linear-gradient(-180deg, #f0f3f6, #e6ebf1 90%);
    border-color: rgba(27, 31, 35, .35);
    background-position: -.5em;
}

.github-star-badge .material-icons {
    height: 16px;
    width: 16px;
    margin-right: 4px;
}

svg#clouds {
    position: fixed;
    bottom: -160px;
    left: -230px;
    z-index: -10;
    width: 1920px;
}

.btn-mic,
.btn-stop {
    cursor: pointer;
    background: none;
    border: none;
    padding: 0;
}

.btn-mic img,
.btn-stop img {
    width: 30px;
    opacity: 0.5;
}

/* Responsive Styles */
@media screen and (max-width: 767px) {

    .card-container>*:not(.circle-link),
    .terminal {
        width: 100%;
    }

    .card:not(.highlight-card) {
        height: 16px;
        margin: 8px 0;
    }

    .card.highlight-card span {
        margin-left: 72px;
    }

    svg#rocket-smoke {
        right: 120px;
        transform: rotate(-5deg);
    }
}

@media screen and (max-width: 575px) {
    svg#rocket-smoke {
        display: none;
        visibility: hidden;
    }
}

We can run the application with SSL enabled.

ng serve --ssl
Open your browser and navigate to https://localhost:4200/. You should be able to start and stop recording, and then download the recorded audio file.
Always keep in mind that accessing microphone requires user permissions. Make sure we test this functionality in a secure context (like https:// or localhost) to ensure that the browser does not block access to the microphone due to security constraints.

The recording will begin after you press the start button, and the stop button will replace the start button. After you click the stop button, an audio preview will appear, and you can click the download button to get the converted audio in WAV format. 




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