Full Trust European Hosting

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

AngularJS Hosting Europe - HostForLIFE :: Angular 2 Bind DropDown List Using Web API

clock April 23, 2025 09:18 by author Peter

The app.component.ts file, which contains the code to bind the dropdown list, is where we will call the external HTML file after creating the project in Visual Studio.


Requirements
Since I created the models in this application using the Database First approach, I'm assuming you know how to utilize an entity framework to retrieve and save the data. To store the data for our languages, create a table in the SQL Server database. See the table script provided below.

CREATE TABLE [dbo].[tbl_language] (
    [languageID] INT IDENTITY(1,1) NOT NULL,
    [language] VARCHAR(200) NOT NULL,
    CONSTRAINT [PK_TBL_LANGUAGE] PRIMARY KEY CLUSTERED (
        [languageID] ASC
    ) WITH (
        PAD_INDEX = OFF,
        STATISTICS_NORECOMPUTE = OFF,
        IGNORE_DUP_KEY = OFF,
        ALLOW_ROW_LOCKS = ON,
        ALLOW_PAGE_LOCKS = ON
    ) ON [PRIMARY]
) ON [PRIMARY];

Insert some sample data into the table.

app.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    templateUrl: './app/binddropdownlisteg.html'
})
export class AppComponent {
}


“app.Component.ts” is the file, which is available for you when you have created your Angular 2 app in an app/app.component.ts file.

Now, create an empty Web API Controller in your Visual Studio by right-clicking on the project - > Add new item - > select Empty Web API Controller from Visual Studio.

Add the code given below, where the Web API Controller is required to get the list of the languages from the table.

Web API Controller and Method
public class languageAPIController : ApiController
{
    private db_sampleentities db = new db_sampleentities();

    // Constructor
    public languageAPIController()
    {
        // Add the following code
        // Problem will be solved
        db.Configuration.ProxyCreationEnabled = false;
    }

    // GET: api/languageAPI
    public IEnumerable<tbl_language> Gettbl_language()
    {
        return db.tbl_language.ToList();
    }
}

Here, in the code db_sampleentities given above is the datacontext class, which is used to communicate with the SQL Server database to fetch the records from the database.

“tbl_language“ is the model, which will hold properties “languageID” and “language” to map with the table tbl_language columns, which we have created in the database.
Service

Create a new TypeScript file in Visual Studio with the name languageservice.service.ts, which acts as a Service for us to call the Web API method and map the data in JSON format.

languageservice.service.ts
import { Injectable } from '@angular/core';
import { Http, Response, RequestOptions, Headers } from '@angular/http';
import { tbl_language } from '../service_models/samplemodels';
import { Observable } from 'rxjs/Rx';

@Injectable()
export class languageService {
    constructor(private http: Http) { }

    getlanguages(): Observable<tbl_language[]> {
        return this.http.get('api/languageAPI')
            .map(res => res.json())
            .catch(this.handleError);
    }

    private handleError(error: Response | any) {
        // In a real world app, we might use a remote logging infrastructure
        let errMsg: string;
        if (error instanceof Response) {
            const body = error.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
    }
}


The code above lets you connect to the Web API method(Getbl_language()) to extract the languages.

binddropdownlisteg.html
Create an HTML file in the Application to display the dropdown, and add the code given below, which will fetch the data by looping through the language data.
<div>
    <label>Language:</label>
    <select [formControl]="sampleform.controls['languageID']">
        <option value="0">--Select--</option>
        <option *ngFor="let lang of languages" value="{{ lang.languageID }}">
            {{ lang.language }}
        </option>
    </select>
</div>


Service Model

Create a TypeScript file and name it languagemodel.ts, which has properties to hold the data from Web API.

languagemodel.ts
export class tbl_language {
    languageID: number;
    language: string;
}


Now, open an app.component.ts file and change the code to include the Service and Model, which we have created in an AppComponent class to bind the dropdown list.

Final Code for app.component.ts file
import { Component } from '@angular/core';

// * Import the language model which contains properties for holding the data
import { tbl_language } from '../Models/languagemodel';

// * Import the name of the service we have created
import { languageService } from '../Services/languageservice.service';
import { FormBuilder, Validators, FormGroup, FormControl } from '@angular/forms';

@Component({
    selector: 'my-app',
    templateUrl: './app/binddropdownlisteg.html',
    providers: [languageService]
})
export class AppComponent {
    errorMessage: string;

    public languages: tbl_language[]; // Create a variable of type tbl_language object
    sampleform: FormGroup;

    constructor(private _languageService: languageService, fb: FormBuilder) {
        this.sampleform = fb.group({
            'languageID': [null] // Will use the property in HTML page
        });
    }

    ngOnInit() {
        // Call the method on initial load of page to bind dropdown
        this.getlanguages();
    }

    // Get the list of languages
    getlanguages() {
        this._languageService.getlanguages().subscribe(
            res => this.languages = res,
            error => this.errorMessage = <any>error
        );
    }
}

Summary
Run the Application by pressing F5 and you can see the output with the the values drowndown list. In this tutorial, we created a table with the languages, a Web API method to fetch the languages, subscribed to the data in Angular 2, and displayed on the screen by binding the data to the dropdown list.



AngularJS Hosting Europe - HostForLIFE :: Use AngularJS to Make an AJAX Call and Get a JSON Response

clock April 10, 2025 08:20 by author Peter

This article describes how to use AngularJS to retrieve data in JSON format. Actually, I was attempting to use AngularJS to make an AJAX request to a web service. I tried this code for that.

<script>
    var myapp = angular.module('myApp', []);

    myapp.controller('control', function ($scope, $http) {
        var call = "WebService1.asmx/HelloWorld";

        $http.post(call)
            .success(function (response) {
                $scope.value = response;
            })
            .error(function (error) {
                alert(error);
            });
    });
</script>

At the WebService I created a method that was returning a string, here I am just using Hello World which is provided in each WebService by default.
[System.Web.Script.Services.ScriptService]
public class WebService1 : System.Web.Services.WebService
{
    [WebMethod]
    public string HelloWorld()
    {
        return "Hello World";
    }
}


After making the call I bound the value into a span using ng-bind.
<body>
    <form id="form1" runat="server">
        <div ng-app="myApp" ng-controller="control">
            <span ng-bind="value"></span>
        </div>
    </form>
</body>


On running the code I got an output like this.

This was not the output I was expecting, I realized that the data was not coming in JSON format, so I had two possible solutions, either return the data from the WebService after converting it to JSON or make every incoming data JSON using AngularJS, I chose the second and changed the code to be as in the following.

<script>
    var myapp = angular.module('myApp', []);

    myapp.controller('control', function ($scope, $http) {
        $http({
            url: "WebService1.asmx/HelloWorld",
            dataType: 'json',
            method: 'POST',
            data: '',
            headers: {
                "Content-Type": "application/json"
            }
        })
        .success(function (response) {
            $scope.value = response.d;
        })
        .error(function (error) {
            alert(error);
        });
    });
</script>


Now, you can see that the call is looking something like an AJAX call made using jQuery but it's from AngularJS, so some of you might feel that this way of calling is easier than the previous one but It's just the extended version of the previous call. Here I have added the success and error functions so that I could determine what type of error I am getting if the code is not working.

Now, we can run the code and see the output.

Now, we are getting the expected result. The source code is available at the top of article.



AngularJS Hosting Europe - HostForLIFE :: Effective Data Management with RxJS Observables in Angular 16

clock March 27, 2025 09:19 by author Peter

Discover how Angular 16 and RxJS Observables work together to effectively manage asynchronous data streams. This post explores important ideas, shows how to apply them to Angular 16 projects, and identifies best practices. To assist you in determining when and when to use observables for the requirements of your application, we also go over the benefits and drawbacks of doing so.

 

Key Concepts and Examples
Creating an Observable

import { Observable } from 'rxjs';
const myObservable = new Observable((observer) => {
  observer.next('First value');
  observer.next('Second value');
  observer.complete();
});
// Subscribing to the Observable
myObservable.subscribe({
  next: (value) => console.log(value),
  complete: () => console.log('Observable completed!'),
});

Using HttpClient with Observables
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
@Component({
  selector: 'app-user-list',
  template: `
    <div *ngFor="let user of users">
      {{ user.name }}
    </div>
  `,
})
export class UserListComponent {
  users: any[] = [];
  constructor(private http: HttpClient) {
    this.http.get('https://jsonplaceholder.typicode.com/users')
      .subscribe((data) => {
        this.users = data as any[];
      });
  }
}


Chaining Operators
import { of } from 'rxjs';
import { map, filter } from 'rxjs/operators';
of(1, 2, 3, 4, 5)
  .pipe(
    filter((num) => num % 2 === 0), // Only even numbers
    map((num) => num * 10)          // Multiply by 10
  )
  .subscribe((result) => console.log(result)); // Output: 20, 40

Pros of Using RxJS Observables in Angular

1. Reactive Architecture
Example: Handling real-time data streams from WebSocket.

import { webSocket } from 'rxjs/webSocket';
const socket$ = webSocket('wss://example.com/socket');
socket$.subscribe((data) =>
  console.log('Message from server:', data)
);

2. Declarative Code
Example: Combining multiple streams


import { interval, combineLatest } from 'rxjs';
const timer1$ = interval(1000);
const timer2$ = interval(1500);
combineLatest([timer1$, timer2$]).subscribe(([val1, val2]) =>
  console.log(`Timer1: ${val1}, Timer2: ${val2}`)
);


3. Seamless Integration with Angular: Angular’s AsyncPipe automatically handles subscriptions and unsubscriptions.
<div *ngIf="(http.get('https://jsonplaceholder.typicode.com/posts') | async) as posts">
  <ul>
    <li *ngFor="let post of posts">
      {{ post.title }}
    </li>
  </ul>
</div>


Cons of Using RxJS Observables in Angular

1. Steep Learning Curve

  • Challenge: Understanding operators like switchMap vs. mergeMap.
  • Example of switchMap: Cancels previous HTTP requests when a new one starts.

searchInput.valueChanges
  .pipe(
    switchMap((query) =>
      this.http.get(`/search?q=${query}`)
    )
  )
  .subscribe((results) =>
    console.log(results)
  );


2. Potential Overhead: Always unsubscribe from streams

this.http
  .get('/api/data')
  .toPromise()
  .then((data) => console.log(data));


3. Memory Leaks: Always unsubscribe from streams

import { Component, OnDestroy } from '@angular/core';
import { Subscription, interval } from 'rxjs';
@Component({
  selector: 'app-example',
  template: '',
})
export class ExampleComponent implements OnDestroy {
  private subscription: Subscription;
  constructor() {
    this.subscription = interval(1000).subscribe(console.log);
  }
  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }
}



Node.js Hosting - HostForLIFE :: Node.js API Design with the Power of Design Patterns

clock March 25, 2025 08:36 by author Peter

One of the most powerful tools for creating scalable and effective APIs is Node.js. Node.js's ability to manage asynchronous tasks well is one of the main reasons for its success. But as projects get more complicated, it becomes crucial to keep the code clear, scalable, and tidy. Design patterns are useful in this situation because they provide tried-and-true answers to typical development problems.


We'll explore some popular design patterns in the context of developing Node.js APIs in this post, along with useful code samples.

1. Singleton Pattern
The Singleton pattern ensures that a class has only one instance and provides a global point to access it. In a Node.js API, this can be beneficial for managing shared resources or configurations.

class Singleton {
  constructor() {

    if (!Singleton.instance) {
      Singleton.instance = this;
    }
    return Singleton.instance;

  }
  // Your class methods here
}

const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // Output: true


The Singleton pattern becomes handy when you want a single point of control for certain aspects of your API, such as managing a shared connection pool or configuration settings.

2. Factory Pattern

The Factory pattern is useful when you want to delegate the responsibility of instantiating objects to a separate factory class. This promotes code separation and flexibility in creating instances.
class Product {

  constructor(name) {
    this.name = name;

  }
}

class ProductFactory {
  createProduct(name) {
    return new Product(name);
  }
}

const productFactory = new ProductFactory();
const product = productFactory.createProduct('Sample Product');

In an API, the Factory pattern can be employed to encapsulate the logic of creating complex objects, allowing for better maintenance and extensibility.

3. Middleware Pattern

In Node.js, middleware plays a pivotal role in processing incoming requests. The middleware pattern involves a chain of functions, each responsible for handling a specific aspect of the request-response cycle.

const middleware1 = (req, res, next) => {

  // Do something before passing control to the next middleware
  next();

};
const middleware2 = (req, res, next) => {

  // Do something else
  next();
};

app.use(middleware1);
app.use(middleware2);

The Middleware pattern in Node.js is crucial for modularizing your API's logic, making it easier to manage and extend as your project evolves.

4. Observer Pattern

The Observer pattern is ideal for implementing event handling mechanisms. In a Node.js API, this can be applied to handle events like data updates or user actions.

class Observer {

  constructor() {
    this.observers = [];
  }

  subscribe(fn) {
    this.observers.push(fn);
  }

  unsubscribe(fn) {
    this.observers = this.observers.filter(subscriber => subscriber !== fn);
  }

  notify(data) {
    this.observers.forEach(observer => observer(data));
  }
}

const dataObserver = new Observer();
dataObserver.subscribe(data => {
  console.log(`Data updated: ${data}`);
});

dataObserver.notify('New data');

The Observer pattern facilitates the creation of loosely coupled components in your API, allowing for better scalability and maintainability.

5. Repository Pattern

The Repository pattern abstracts the data access layer from the business logic. This is particularly beneficial for managing database interactions in a Node.js API.
class UserRepository {

  constructor(database) {
    this.database = database;
  }

  getUserById(userId) {
    return this.database.query(`SELECT * FROM users WHERE id = ${userId}`);
  }

  saveUser(user) {
    return this.database.query('INSERT INTO users SET ?', user);
  }
}

const db = /* your database connection */;
const userRepository = new UserRepository(db);
const user = { name: 'John Doe', email: '[email protected]' };
userRepository.saveUser(user);

The Repository pattern aids in decoupling your API's business logic from the underlying data storage, facilitating easier testing and maintenance.

Conclusion

Incorporating design patterns in your Node.js API can greatly enhance its architecture, making it more maintainable and scalable. The examples provided above cover just a glimpse of the design patterns available for Node.js development. As you continue to explore and implement these patterns, you'll find your code becoming more modular, flexible, and easier to maintain.

Design patterns are powerful tools in the hands of developers, providing effective solutions to common problems encountered in API development. By adopting these patterns judiciously, you can ensure the long-term success and sustainability of your Node.js API projects.




AngularJS Hosting Europe - HostForLIFE :: Configure Build Environments With Angular

clock March 13, 2025 08:36 by author Peter

Managing various settings and configurations for development, staging, production, or any other environment requires the ability to configure build environments in Angular. Through the environments folder and the angular.json file, Angular offers an integrated solution for this.

To set up build environments in an Angular application, follow these steps.

Step 1: Establish the project
ng new my-angular-app

Step 2. Create Environment Files
Angular typically comes with two environment files out of the box.

  • src/environments/environment.ts (for development)
  • src/environments/environment.prod.ts (for production)

You can create additional files for other environments (e.g., staging)

Each file exports an object with environment-specific properties.
// environment.ts (development)
export const environment = {
  production: false,
  apiBaseUrl: 'http://localhost:4000/api',
};

// environment.prod.ts (production)
export const environment = {
  production: true,
  apiBaseUrl: 'https://api.example.com',
};

// environment.staging.ts (staging)
export const environment = {
  production: false,
  apiBaseUrl: 'https://staging-api.example.com',
};

Step 3. Configure File Replacements
Modify the angular.json file to specify file replacements for different build configurations.
Locate the fileReplacements section under the configurations key in your Angular project.
"configurations": {
  "production": {
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.prod.ts"
      }
    ]
  },
  "staging": {
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.staging.ts"
      }
    ]
  }
}

Step 4. Add Build Scripts
Update the angular.json file to define build configurations for new environments.
"architect": {
  "build": {
    "configurations": {
      "production": {
        ...
      },
      "staging": {
        "fileReplacements": [
          {
            "replace": "src/environments/environment.ts",
            "with": "src/environments/environment.staging.ts"
          }
        ],
        "optimization": true,
        "outputHashing": "all",
        "sourceMap": false,
        "extractCss": true,
        "namedChunks": false,
        "aot": true,
        "buildOptimizer": true,
        "budgets": [
          {
            "type": "initial",
            "maximumWarning": "2mb",
            "maximumError": "5mb"
          }
        ]
      }
    }
  }
}


Step 5. Build for Specific Environments
Use the --configuration flag to build for specific environments.
ng build --configuration=staging
ng build --configuration=production

For development, the default build configuration applies unless overridden.

Step 6. Use Environment Variables in Code
In your Angular code, use the environment object to access environment-specific values.
import { environment } from '../environments/environment';
console.log('API Base URL:', environment.apiBaseUrl);
if (environment.production) {
  console.log('Running in production mode');
}


Step 7. Add Additional Settings
For complex builds, you can.

  • Use environment variables with tools like dotenv for dynamic replacements.
  • Integrate third-party CI/CD tools to manage deployment-specific configurations.

By following these steps, you can manage multiple build environments efficiently in your Angular application. Let me know if you'd like further assistance or an example.



Node.js Hosting - HostForLIFE :: Node.js App with User Authentication and Docker Deployment

clock February 12, 2025 07:01 by author Peter

Node.js web application development enables the development of scalable and effective platforms. You will learn how to put up a basic application with a dashboard interface and user authentication in this tutorial. The database will be MongoDB, the web framework will be Express, and the templating will be done with EJS. For simpler deployment, we will also use Docker to containerize our application.

Before you begin, ensure you have the following installed on your system:

  • Node.js and npm
  • Docker
  • Docker Compose
  • A text editor or IDE of your choice

Step 1. Setting Up Your Project
Initialize a New Node.js Project

  • Open your terminal.
  • Create a new directory for your project and navigate into it:


mkdir nodejs-app
cd nodejs-app


Initialize a new Node.js project:
npm init -y

Install Dependencies
Install Express, EJS, Mongoose, and other necessary packages:
npm install express ejs mongoose bcryptjs express-session passport passport-local

Step 2. Create the Application Structure
Create the necessary directories and files for your application:
nodejs-app/
│
├── app.js
├── Dockerfile
├── docker-compose.yml
├── package.json
├── routes/
│   ├── index.js
│   ├── user.js
├── config/
│   ├── passportConfig.js
├── views/
│   ├── login.ejs
│   ├── register.ejs
│   ├── dashboard.ejs
│   ├── layout.ejs
│   └── partials/
│       └── messages.ejs
├── models/
│   ├── User.js
└── public/
    ├── css/
        ├── style.css


Here is a shell script (create-nodejs-app.sh) to automatically create the directory structure for your Node.js application:
#!/bin/bash

# Define the folder structure
mkdir -p nodejs-app/{routes,config,views,models,public/css}


# Create the necessary files
touch nodejs-app/app.js
touch nodejs-app/Dockerfile
touch nodejs-app/docker-compose.yml
touch nodejs-app/package.json
touch nodejs-app/routes/index.js
touch nodejs-app/routes/user.js
touch nodejs-app/config/passportConfig.js
touch nodejs-app/views/login.ejs
touch nodejs-app/views/register.ejs
touch nodejs-app/views/dashboard.ejs
touch nodejs-app/views/layout.ejs
touch nodejs-app/views/partials/messages.ejs
touch nodejs-app/models/User.js
touch nodejs-app/public/css/style.css

# Confirmation message
echo "Node.js app folder structure created successfully!"


Step 3. Developing the Backend
Set Up Express and Middleware
In app.js, Set up your Express application and middleware to handle requests.

        const express = require('express');
        const mongoose = require('mongoose');
        const session = require('express-session');
        const flash = require('connect-flash');
        const passport = require('passport');
        const app = express();
        const port = 3000;

        // Passport Config
        require('./config/passportConfig')(passport);

        // DB Config
        mongoose.connect('mongodb://mongo:27017/nodejs-app', { useNewUrlParser: true, useUnifiedTopology: true })
            .then(() => console.log('MongoDB Connected'))
            .catch(err => console.log(err));

        // Middleware
        app.use(express.urlencoded({ extended: false }));
        app.use(express.static('public'));

        // EJS
        app.set('view engine', 'ejs');

        // Express Session
        app.use(session({
            secret: 'secret',
            resave: true,
            saveUninitialized: true
        }));

        // Passport middleware
        app.use(passport.initialize());
        app.use(passport.session());

        // Connect Flash
        app.use(flash());

        // Global Variables
        app.use((req, res, next) => {
            res.locals.success_msg = req.flash('success_msg');
            res.locals.error_msg = req.flash('error_msg');
            res.locals.error = req.flash('error');
            next();
        });

        // Routes
        app.use('/', require('./routes/index'));
        app.use('/users', require('./routes/user'));

        // Start Server
        app.listen(port, () => {
            console.log(`Server started on port ${port}`);
        });


Configure Passport for user authentication
Database Models
Use Mongoose to define models in models/User.js.

    const mongoose = require('mongoose');

    const UserSchema = new mongoose.Schema({
        name: {
            type: String,
            required: true
        },
        email: {
            type: String,
            required: true,
            unique: true
        },
        password: {
            type: String,
            required: true
        },
        date: {
            type: Date,
            default: Date.now
        }
    });

    const User = mongoose.model('User', UserSchema);

    module.exports = User;


User Authentication
Implement registration and login functionality in routes/user.js.

     const express = require('express');
    const router = express.Router();
    const bcrypt = require('bcryptjs');
    const passport = require('passport');
    const User = require('../models/User');

    // Register Page
    router.get('/register', (req, res) => res.render('register'));

    // Register Handle
    router.post('/register', (req, res) => {
        const { name, email, password, password2 } = req.body;
        let errors = [];

        // Validation
        if (!name || !email || !password || !password2) {
            errors.push({ msg: 'Please fill in all fields' });
        }

        if (password !== password2) {
            errors.push({ msg: 'Passwords do not match' });
        }

        if (errors.length > 0) {
            res.render('register', { errors, name, email, password, password2 });
        } else {
            User.findOne({ email: email })
                .then(user => {
                    if (user) {
                        errors.push({ msg: 'Email already exists' });
                        res.render('register', { errors, name, email, password, password2 });
                    } else {
                        const newUser = new User({ name, email, password });

                        bcrypt.genSalt(10, (err, salt) => {
                            bcrypt.hash(newUser.password, salt, (err, hash) => {
                                if (err) throw err;
                                newUser.password = hash;
                                newUser.save()
                                    .then(user => {
                                        req.flash('success_msg', 'You are now registered and can log in');
                                        res.redirect('/users/login');
                                    })
                                    .catch(err => console.log(err));
                            });
                        });
                    }
                });
        }
    });

    // Login Page
    router.get('/login', (req, res) => res.render('login'));

    // Login Handle
    router.post('/login', (req, res, next) => {
        passport.authenticate('local', {
            successRedirect: '/dashboard',
            failureRedirect: '/users/login',
            failureFlash: true
        })(req, res, next);
    });

    // Logout Handle
    router.get('/logout', (req, res) => {
        req.logout(() => {
            req.flash('success_msg', 'You are logged out');
            res.redirect('/users/login');
        });
    });

    module.exports = router;


Utilize Passport for handling authentication. config/passportConfig.js
const LocalStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

// Load User model
const User = require('../models/User');

module.exports = function (passport) {
    passport.use(new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
        User.findOne({ email: email })
            .then(user => {
                if (!user) {
                    return done(null, false, { message: 'That email is not registered' });
                }

                bcrypt.compare(password, user.password, (err, isMatch) => {
                    if (err) throw err;
                    if (isMatch) {
                        return done(null, user);
                    } else {
                        return done(null, false, { message: 'Password incorrect' });
                    }
                });
            })
            .catch(err => console.log(err));
    }));

    passport.serializeUser((user, done) => {
        done(null, user.id);
    });

    passport.deserializeUser((id, done) => {
        User.findById(id, (err, user) => {
            done(err, user);
        });
    });
};


routes/user.js
const express = require('express');
const router = express.Router();
const { ensureAuthenticated } = require('../config/auth');

// Welcome Page
router.get('/', (req, res) => res.render('welcome'));

// Dashboard Page
router.get('/dashboard', ensureAuthenticated, (req, res) =>
    res.render('dashboard', {
        user: req.user
    })
);

module.exports = router;


config/auth.js
module.exports = {
    ensureAuthenticated: function (req, res, next) {
        if (req.isAuthenticated()) {
            return next();
        }
        req.flash('error_msg', 'Please log in to view this resource');
        res.redirect('/users/login');
    }
};


Step 4. Creating the Frontend
EJS Templates
Create views for registration, login, and the dashboard in the views/ directory.
views/register.ejs

        <%- include('layout') %>
        <form action="/users/register" method="POST">
            <div class="form-group">
                <input type="text" name="name" class="form-control" placeholder="Name">
            </div>
            <div class="form-group">
                <input type="email" name="email" class="form-control" placeholder="Email">
            </div>
            <div class="form-group">
                <input type="password" name="password" class="form-control" placeholder="Password">
            </div>
            <div class="form-group">
                <input type="password" name="password2" class="form-control" placeholder="Confirm Password">
            </div>
            <button type="submit" class="btn btn-primary">Register</button>
        </form>


views/login.ejs
<%- include('layout') %>
<form action="/users/login" method="POST">
    <div class="form-group">
        <input type="email" name="email" class="form-control" placeholder="Email">
    </div>
    <div class="form-group">
        <input type="password" name="password" class="form-control" placeholder="Password">
    </div>
    <button type="submit" class="btn btn-primary">Login</button>
</form>


views/dashboard.ejs
<%- include('layout') %>
<h1>Welcome, <%= user.name %>!</h1>
<a href="/users/logout" class="btn btn-danger">Logout</a>

JavaScript
views/layout.ejs
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Node.js App</title>
    <link rel="stylesheet" href="/css/style.css">
</head>
<body>
    <nav>
        <a href="/">Home</a>
        <a href="/users/login">Login</a>
        <a href="/users/register">Register</a>
    </nav>
    <div class="container">
        <%- include('partials/messages') %>
    </div>
</body>
</html>


Create the partials Directory and messages.ejs
Inside your views directory, create a new folder called partials.
Inside this partials folder, create a file called messages.ejs.

Here is an example of the content for messages.ejs:
    <% if (typeof success_msg != 'undefined') { %>
        <div class="alert alert-success">
            <%= success_msg %>
        </div>
    <% } %>

    <% if (typeof error_msg != 'undefined') { %>
        <div class="alert alert-danger">
            <%= error_msg %>
        </div>
    <% } %>

    <% if (typeof errors != 'undefined' && errors.length > 0) { %>
        <div class="alert alert-danger">
            <ul>
            <% errors.forEach(function(error) { %>
                <li><%= error.msg %></li>
            <% }) %>
            </ul>
        </div>
    <% } %>


Static Files
Style your application using CSS in the public/css/style.css file.

    /* Reset some default browser styles */
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    body {
        font-family: Arial, sans-serif;
        background-color: #f4f4f4;
        color: #333;
        line-height: 1.6;
        margin: 0;
        padding: 0;
    }

    /* Container */
    .container {
        max-width: 1170px;
        margin: 0 auto;
        padding: 20px;
    }

    /* Navigation */
    nav {
        background: #333;
        color: #fff;
        padding: 15px;
        text-align: center;
    }

    nav a {
        color: #fff;
        text-decoration: none;
        margin: 0 10px;
    }

    nav a:hover {
        text-decoration: underline;
    }

    /* Form Styling */
    form {
        background: #fff;
        padding: 20px;
        margin-top: 20px;
        border-radius: 5px;
        box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    }

    .form-group {
        margin-bottom: 15px;
    }

    .form-group input {
        width: 100%;
        padding: 10px;
        border: 1px solid #ccc;
        border-radius: 5px;
    }

    button {
        background: #333;
        color: #fff;
        border: 0;
        padding: 10px 15px;
        cursor: pointer;
        border-radius: 5px;
    }

    button:hover {
        background: #555;
    }

    /* Messages */
    .alert {
        padding: 10px;
        background-color: #f4f4f4;
        color: #333;
        margin-bottom: 20px;
        border: 1px solid #ccc;
    }

    .alert-success {
        background-color: #dff0d8;
        color: #3c763d;
    }

    .alert-error {
        background-color: #f2dede;
        color: #a94442;
    }

    /* Dashboard */
    h1 {
        font-size: 24px;
        margin-bottom: 20px;
    }

    .btn-danger {
        background-color: #e74c3c;
    }

    .btn-danger:hover {
        background-color: #c0392b;
    }


Step 5. Dockerizing the Application

    Dockerfile
        Create a Dockerfile to specify the build process for your application.

        FROM node:16

        WORKDIR /app

        COPY package*.json ./

        RUN npm install

        COPY . .

        EXPOSE 3000

        CMD ["node", "app.js"]


Docker Compose
Define services, including your Node.js app and MongoDB, in docker-compose.yml.

    version: '3'
    services:
      app:
        build: .
        ports:
          - "3000:3000"
        depends_on:
          - mongo
      mongo:
        image: mongo
        ports:
          - "27017:27017"


Step 6. Running Your Application
Build and Run with Docker Compose

docker-compose up --build


Access the App: Go to http://localhost:3000 in your browser.

Access the App: Go to http://localhost:3000 in your browser.

HostForLIFE.eu Node.js Hosting
HostForLIFE.eu 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 customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



AngularJS Hosting Europe - HostForLIFE :: Function-Based Interceptor in Angular

clock February 5, 2025 06:09 by author Peter

An excellent method for managing and altering HTTP requests and answers across your application is to use Angular interceptors. Although classes are typically used to build interceptors, function-based interceptors can be used for more straightforward and reusable code.


We'll go over how to make and use function-based interceptors in Angular in this blog, along with simple examples for increased flexibility and clarity.

What is a function-based Interceptor?
A function-based interceptor is a simpler and more flexible option compared to a class-based interceptor. Instead of creating a whole class with an intercept method, you put your logic into individual functions. This approach helps with,

  • Separation of Concerns: Smaller, focused functions are easier to test and maintain.
  • Reusability: You can reuse the interceptor logic by sharing or combining multiple functions.

Benefits of Function-Based Interceptors

  • Less Setup: You only need a function, not an entire class.
  • Easier Testing: It’s simpler to test individual functions.
  • Flexible: You can combine several functions to handle complex request/response processes.

How to implement a function-based Interceptor?
Let us create an angular project with the imported HttpClientModule.
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { HttpClientModule } from '@angular/common/http';
    import { AppComponent } from './app.component';

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

TypeScript
Create a function-based interceptor - a function-based interceptor works by using a factory to handle the request/response logic.

import { HttpInterceptorFn } from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  console.log('Intercepting Request:', req);

  // Add an Authorization header
  const token = 'your-token-here';
  const clonedRequest = req.clone({
    setHeaders: {
      Authorization: `Bearer ${token}`,
    },
  });

  console.log('Modified Request:', clonedRequest);

  // Forward the modified request
  return next(clonedRequest);
};


Key Points

  • Factory Function: Use HttpInterceptorFn to define the interceptor.
  • Modify Request: Use req.clone() to create a modified version of the request.
  • Forward Request: Send the cloned request to the next step with next.

Register the Function Interceptor
To register the function-based interceptor, use the provided HTTP client configuration in your AppModule or feature module.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule, provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptor } from './auth-interceptor.fn';

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

Why Use provideHttpClient?
Introduced in Angular 15, this modern API makes it easier to configure the HTTP client and supports function-based interceptors directly.

Use the Interceptor in an HTTP Request

Now that the interceptor is registered test it by making an HTTP request.
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'function-based-Interceptor';

  constructor(private http: HttpClient) { }

  ngOnInit(): void {
    this.http.get('https://jsonplaceholder.typicode.com/posts').subscribe((data) => {
      console.log('Response:', data);
    });
  }
}


Let us execute the app and validate whether the interceptor was properly executed.



AngularJS Hosting Europe - HostForLIFE :: Understanding the Angular Lifecycle Hooks

clock January 22, 2025 08:17 by author Peter

In Angular, components go through a series of stages from their creation to destruction. These stages are collectively known as the Angular lifecycle. Understanding the lifecycle hooks provided by Angular allows developers to tap into key moments in a component's lifecycle to perform initialization, cleanup, and other crucial operations. This article provides an in-depth look at each of these lifecycle hooks and how to use them effectively.

Angular Lifecycle Hooks
Here is a list of the primary lifecycle hooks in Angular.

  • ngOnChanges
  • ngOnInit
  • ngDoCheck
  • ngAfterContentInit
  • ngAfterContentChecked
  • ngAfterViewInit
  • ngAfterViewChecked
  • ngOnDestroy

Let's explore each of these hooks in detail.

1. ngOnChanges

When it’s called: This hook is called whenever an input property bound to a component changes. It’s called before ngOnInit and whenever the input properties are updated.
Use case: Use ngOnChanges to act on changes to input properties from the parent component.

Example
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
@Component({
  selector: 'app-child',
  template: '<p>{{data}}</p>',
})
export class ChildComponent implements OnChanges {
  @Input() data: string;
  ngOnChanges(changes: SimpleChanges) {
    console.log('ngOnChanges called', changes);
  }
}


2. ngOnInit
When it’s called: This hook is called once, after the first ngOnChanges. It’s typically used for component initialization.
Use case: Use ngOnInit to perform component initialization, like fetching data.

Example
import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-example',
  template: '<p>Example works!</p>',
})
export class ExampleComponent implements OnInit {
  ngOnInit() {
    console.log('ngOnInit called');
  }
}


3. ngDoCheck
When it’s called: This hook is called during every change detection run. It’s useful for custom change detection.
Use case: Use ngDoCheck to implement custom change detection logic.

Example
import { Component, DoCheck } from '@angular/core';
@Component({
  selector: 'app-check',
  template: '<p>Check works!</p>',
})
export class CheckComponent implements DoCheck {
  ngDoCheck() {
    console.log('ngDoCheck called');
  }
}


4. ngAfterContentInit
When it’s called: This hook is called after Angular projects external content into the component’s view (ng-content).
Use case: Use ngAfterContentInit to respond to content projection into the component.

Example
import { Component, AfterContentInit } from '@angular/core';
@Component({
  selector: 'app-content',
  template: '<ng-content></ng-content>',
})
export class ContentComponent implements AfterContentInit {
  ngAfterContentInit() {
    console.log('ngAfterContentInit called');
  }
}


5. ngAfterContentChecked
When it’s called: This hook is called after every check of the component’s projected content.
Use case: Use ngAfterContentChecked to act after the content is checked.

Example
import { Component, AfterContentChecked } from '@angular/core';
@Component({
  selector: 'app-content-check',
  template: '<ng-content></ng-content>',
})
export class ContentCheckComponent implements AfterContentChecked {
  ngAfterContentChecked() {
    console.log('ngAfterContentChecked called');
  }
}


6. ngAfterViewInit
When it’s called: This hook is called after Angular initializes the component’s views and child views.
Use case: Use ngAfterViewInit to perform actions after the component’s view is initialized.

Example
import { Component, AfterViewInit } from '@angular/core';
@Component({
  selector: 'app-view-init',
  template: '<p>View Init works!</p>',
})
export class ViewInitComponent implements AfterViewInit {
  ngAfterViewInit() {
    console.log('ngAfterViewInit called');
  }
}


7. ngAfterViewChecked
When it’s called: This hook is called after every check of the component’s view.
Use case: Use ngAfterViewChecked to act after the component’s view is checked.

Example
import { Component, AfterViewChecked } from '@angular/core';
@Component({
  selector: 'app-view-check',
  template: '<p>View Check works!</p>',
})
export class ViewCheckComponent implements AfterViewChecked {
  ngAfterViewChecked() {
    console.log('ngAfterViewChecked called');
  }
}

8. ngOnDestroy
When it’s called: This hook is called just before Angular destroys the component.
Use case: Use ngOnDestroy for cleanup, like unsubscribing from observables and detaching event handlers.

Example
import { Component, OnDestroy } from '@angular/core';
@Component({
  selector: 'app-destroy',
  template: '<p>Destroy works!</p>',
})
export class DestroyComponent implements OnDestroy {
  ngOnDestroy() {
    console.log('ngOnDestroy called');
  }
}

Lifecycle Sequence
Understanding the order of these hooks is crucial for correctly implementing logic that depends on the component's lifecycle stages.

  • ngOnChanges
  • ngOnInit
  • ngDoCheck
  • ngAfterContentInit
  • ngAfterContentChecked
  • ngAfterViewInit
  • ngAfterViewChecked
  • ngOnDestroy

Practical Use Cases

  • ngOnInit: Ideal for initialization tasks like fetching data from a service.
  • ngOnChanges: Useful for reacting to changes in input properties.
  • ngOnDestroy: Perfect for cleaning up resources, like unsubscribing from observables.
  • ngAfterViewInit: Great for manipulating the DOM after the view is initialized.

Conclusion
Mastering Angular lifecycle hooks is essential for building robust and maintainable Angular applications. By understanding when and how to use each hook, developers can ensure their components are properly initialized, updated, and cleaned up. This not only leads to better performance but also improves code organization and readability.



European Visual Studio 2022 Hosting - HostForLIFE :: Use Endpoints Explorer with .http Files in Visual Studio

clock January 17, 2025 07:07 by author Peter

Through the integration of Endpoints Explorer, a potent tool that functions flawlessly with.http files, Visual Studio 2022 has completely transformed API testing. This combination removes the need for third-party tools like Postman or Swagger by enabling developers to design, administer, and run API tests straight from the IDE.

With Endpoints Explorer, developers enjoy.

  • Reduced Context Switching
  • Increased Productivity
  • Streamlined API Testing Workflow

What Problem Does It Solve?
Before this feature, developers relied heavily on external tools to test their APIs. This involved.

  • Exporting endpoints or configurations manually.
  • Managing additional setups outside their IDE.

Endpoints Explorer fixes this by embedding API testing into Visual Studio, making the process smooth and time-efficient.

How to use Endpoints Explorer?
Open Your Project

Ensure you are using Visual Studio 2022 version 17.6 or later and load your project.

Access Endpoints Explorer
Navigate to View -> Other Windows -> Endpoints Explorer.


This tool scans your project for,

  • Controllers marked with the [ApiController] attribute.
  • Minimal API configurations.

You’ll see a comprehensive list of all available endpoints.

Working with Endpoints
Right-clicking an endpoint in the explorer provides two options.

Option 1. Open in Editor
This opens the corresponding controller or minimal API definition in the code editor. Perfect for quick reviews and edits.

Option 2. Generate Request
Selecting this option generates an API request in a .http file, enabling you to test the endpoint directly in Visual Studio.

Working with .http Files

  • If a .HTTP file (named after your project) exists, a new request is added to it.
  • Otherwise, a new .http file is created automatically.

Writing and Sending HTTP Requests
The .HTTP file is where you create and send requests. It supports:

  • GET, POST, PUT, DELETE requests.
  • Custom headers, query parameters, and JSON payloads.

Here’s an example of a request.
### Fetch all users
GET https://your-api-url.com/users
Authorization: Bearer YOUR-TOKEN

### Add a user
POST https://your-api-url.com/users
Content-Type: application/json

{
"name": "John Doe",
"email": "[email protected]"
}

Benefits of Endpoints Explorer + .http File Combo

  • All-in-One Workflow: No need to switch between IDE and external tools like Postman.
  • Collaboration Made Easy: Share .HTTP files with your team as part of your repository for consistent API testing.
  • Integrated Experience: Quickly debug endpoints and iterate through development with minimal disruptions.
  • Simpler Configuration: Directly test APIs without exporting Postman collections or Swagger setups.

Best Practices for Using Endpoints Explorer

  • Organize Requests: Group your .http requests by features or endpoints to keep your testing structured.
  • Leverage Comments: Add meaningful comments in .HTTP files to describe each request.
  • Commit .http Files to Source Control: Share and track changes with your team to maintain consistency.

Conclusion
Visual Studio 2022 revolutionizes API testing by providing developers with a quicker, more effective workflow with the use of Endpoints Explorer and.http files. For more productivity, embrace the integrated experience and bid adieu to extraneous tools. All set to give it a try? Upgrade to Visual Studio 2022 (version 17.6 or above) and start exploring the world of smooth API testing right now! Do you know how to use Endpoints Explorer? Tell us about your experience in the space provided here.



AngularJS Hosting Europe - HostForLIFE :: Configure Build Environments With Angular

clock January 10, 2025 06:47 by author Peter

Configuring build environments in Angular is essential for managing different settings and configurations for development, staging, production, or any other environments. Angular provides a built-in mechanism for this via the angular.json file and the environments folder.


Here are steps to configure build environments in an Angular application.

Step 1. Create project
ng new my-angular-app

Step 2. Create Environment Files
Angular typically comes with two environment files out of the box.
src/environments/environment.ts (for development)
src/environments/environment.prod.ts (for production)

You can create additional files for other environments (e.g., staging).

Each file exports an object with environment-specific properties.
// environment.ts (development)
export const environment = {
  production: false,
  apiBaseUrl: 'http://localhost:4000/api',
};

// environment.prod.ts (production)
export const environment = {
  production: true,
  apiBaseUrl: 'https://api.example.com',
};

// environment.staging.ts (staging)
export const environment = {
  production: false,
  apiBaseUrl: 'https://staging-api.example.com',
};


Step 3. Configure File Replacements
Modify the angular.json file to specify file replacements for different build configurations.

Locate the fileReplacements section under the configurations key in your Angular project.
"configurations": {
  "production": {
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.prod.ts"
      }
    ]
  },
  "staging": {
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.staging.ts"
      }
    ]
  }
}


Step 4. Add Build Scripts
Update the angular.json file to define build configurations for new environments.
"architect": {
  "build": {
    "configurations": {
      "production": {
        ...
      },
      "staging": {
        "fileReplacements": [
          {
            "replace": "src/environments/environment.ts",
            "with": "src/environments/environment.staging.ts"
          }
        ],
        "optimization": true,
        "outputHashing": "all",
        "sourceMap": false,
        "extractCss": true,
        "namedChunks": false,
        "aot": true,
        "buildOptimizer": true,
        "budgets": [
          {
            "type": "initial",
            "maximumWarning": "2mb",
            "maximumError": "5mb"
          }
        ]
      }
    }
  }
}

Step 5. Build for Specific Environments
Use the --configuration flag to build for specific environments.
ng build --configuration=staging
ng build --configuration=production


For development, the default build configuration applies unless overridden.

Step 6. Use Environment Variables in Code
In your Angular code, use the environment object to access environment-specific values.
import { environment } from '../environments/environment';
console.log('API Base URL:', environment.apiBaseUrl);
if (environment.production) {
  console.log('Running in production mode');
}


Step 7. Add Additional Settings
For complex builds, you can.

  • Use environment variables with tools like dotenv for dynamic replacements.
  • Integrate third-party CI/CD tools to manage deployment-specific configurations.

By following these steps, you can manage multiple build environments efficiently in your Angular application. Let me know if you'd like further assistance or an example.



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