JavaScript closure inside loops – simple practical example

https://stackoverflow.com/q/750486/4964569

Well, the problem is that the variable i, within each of your anonymous functions, is bound to the same variable outside of the function.

Classic solution: Closures

What you want to do is bind the variable within each function to a separate, unchanging value outside of the function:

var funcs = [];

function createfunc(i) {
  return function() {
    console.log("My value: " + i);
  };
}

for (var i = 0; i < 3; i++) {
  funcs[i] = createfunc(i);
}

for (var j = 0; j < 3; j++) {
  // and now let's run each one to see
  funcs[j]();
}
 Run code snippet

Since there is no block scope in JavaScript – only function scope – by wrapping the function creation in a new function, you ensure that the value of “i” remains as you intended.


2015 Solution: forEach

With the relatively widespread availability of the Array.prototype.forEach function (in 2015), it’s worth noting that in those situations involving iteration primarily over an array of values, .forEach()provides a clean, natural way to get a distinct closure for every iteration. That is, assuming you’ve got some sort of array containing values (DOM references, objects, whatever), and the problem arises of setting up callbacks specific to each element, you can do this:

var someArray = [ /* whatever */ ];
// ...
someArray.forEach(function(arrayElement) {
  // ... code code code for this one element
  someAsynchronousFunction(arrayElement, function() {
    arrayElement.doSomething();
  });
});

The idea is that each invocation of the callback function used with the .forEach loop will be its own closure. The parameter passed in to that handler is the array element specific to that particular step of the iteration. If it’s used in an asynchronous callback, it won’t collide with any of the other callbacks established at other steps of the iteration.

If you happen to be working in jQuery, the $.each() function gives you a similar capability.


ES6 solution: let

ECMAScript 6 (ES6) introduces new let and const keywords that are scoped differently than var-based variables. For example, in a loop with a let-based index, each iteration through the loop will have a new value of i where each value is scoped inside the loop, so your code would work as you expect. There are many resources, but I’d recommend 2ality’s block-scoping post as a great source of information.

for (let i = 0; i < 3; i++) {
  funcs[i] = function() {
    console.log("My value: " + i);
  };
}

Beware, though, that IE9-IE11 and Edge prior to Edge 14 support let but get the above wrong (they don’t create a new i each time, so all the functions above would log 3 like they would if we used var). Edge 14 finally gets it right.

Advertisements
Posted in Education and Training, Problem solving, Programming, Uncategorized | Leave a comment

Angular 7 – JWT Authentication Example & Tutorial

From https://jasonwatmore.com/post/2018/11/16/angular-7-jwt-authentication-example-tutorial

 

Angular 7 Tutorial Project Structure

The project and code structure of the tutorial mostly follows the best practice recommendations in the official Angular Style Guide, with a few of my own tweaks here and there.

Each feature has it’s own folder (home & login), other shared/common code such as services, models, guards etc are placed in folders prefixed with an underscore to easily differentiate them and group them together at the top of the folder structure.

The index.ts files in each folder are barrel files that group the exported modules from a folder together so they can be imported using the folder path instead of the full module path and to enable importing multiple modules in a single import (e.g. import { AuthenticationService, UserService } from '../_services').

A path alias ‘@’ has been configured in the tsconfig.json and webpack.config.js that maps to the ‘/src/app’ directory. This allows imports to be relative to the ‘/src/app’ folder by prefixing the import path with ‘@’, removing the need to use long relative paths like import MyComponent from '../../../MyComponent'.

Here’s the tutorial project structure:

Below are brief descriptions and the code for the main files of the example authentication application, all the tutorial code is available in the github project linked at the top of the post.

 

Angular 7 Auth Guard

Path: /src/app/_guards/auth.guard.ts

The auth guard is an angular route guard that’s used to prevent unauthenticated users from accessing restricted routes, it does this by implementing the CanActivate interface which allows the guard to decide if a route can be activated with the canActivate() method. If the method returns true the route is activated (allowed to proceed), otherwise if the method returns false the route is blocked.

The auth guard uses the authentication service to check if the user is logged in, if they are logged in it returns true from the canActivate()method, otherwise it returns false and redirects the user to the login page.

Angular route guards are attached to routes in the router config, this auth guard is used in app.routing.ts to protect the home page route.

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

import { AuthenticationService } from '@/_services';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
    constructor(
        private router: Router,
        private authenticationService: AuthenticationService
    ) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const currentUser = this.authenticationService.currentUserValue;
        if (currentUser) {
            // logged in so return true
            return true;
        }

        // not logged in so redirect to login page with the return url
        this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
        return false;
    }
}
 

Angular 7 Http Error Interceptor

Path: /src/app/_helpers/error.interceptor.ts

The Error Interceptor intercepts http responses from the api to check if there were any errors. If there is a 401 Unauthorized response the user is automatically logged out of the application, all other errors are re-thrown to be caught by the calling service so an alert can be displayed to the user.

It’s implemented using the HttpInterceptor class that was introduced in Angular 4.3 as part of the new HttpClientModule. By extending the HttpInterceptor class you can create a custom interceptor to catch all error responses from the server in a single location.

Http interceptors are added to the request pipeline in the providers section of the app.module.ts file.

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

import { AuthenticationService } from '@/_services';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
    constructor(private authenticationService: AuthenticationService) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(catchError(err => {
            if (err.status === 401) {
                // auto logout if 401 response returned from api
                this.authenticationService.logout();
                location.reload(true);
            }

            const error = err.error.message || err.statusText;
            return throwError(error);
        }))
    }
}
 

Angular 7 Fake Backend Provider

Path: /src/app/_helpers/fake-backend.ts

The fake backend provider enables the example to run without a backend / backendless, I created it so I could focus the example and tutorial just on the angular code, and also so it would work on StackBlitz.

It’s implemented using the HttpInterceptor class that was introduced in Angular 4.3 as part of the new HttpClientModule. By extending the HttpInterceptor class you can create a custom interceptor to modify http requests before they get sent to the server. In this case the FakeBackendInterceptor intercepts certain requests based on their URL and provides a fake response instead of going to the server.

import { Injectable } from '@angular/core';
import { HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS } from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs';
import { delay, mergeMap, materialize, dematerialize } from 'rxjs/operators';

import { User } from '@/_models';

@Injectable()
export class FakeBackendInterceptor implements HttpInterceptor {
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const users: User[] = [
            { id: 1, username: 'test', password: 'test', firstName: 'Test', lastName: 'User' }
        ];

        const authHeader = request.headers.get('Authorization');
        const isLoggedIn = authHeader && authHeader.startsWith('Bearer fake-jwt-token');

        // wrap in delayed observable to simulate server api call
        return of(null).pipe(mergeMap(() => {

            // authenticate - public
            if (request.url.endsWith('/users/authenticate') && request.method === 'POST') {
                const user = users.find(x => x.username === request.body.username && x.password === request.body.password);
                if (!user) return error('Username or password is incorrect');
                return ok({
                    id: user.id,
                    username: user.username,
                    firstName: user.firstName,
                    lastName: user.lastName,
                    token: `fake-jwt-token`
                });
            }

            // get all users
            if (request.url.endsWith('/users') && request.method === 'GET') {
                if (!isLoggedIn) return unauthorised();
                return ok(users);
            }

            // pass through any requests not handled above
            return next.handle(request);
        }))
        // call materialize and dematerialize to ensure delay even if an error is thrown (https://github.com/Reactive-Extensions/RxJS/issues/648)
        .pipe(materialize())
        .pipe(delay(500))
        .pipe(dematerialize());

        // private helper functions

        function ok(body) {
            return of(new HttpResponse({ status: 200, body }));
        }

        function unauthorised() {
            return throwError({ status: 401, error: { message: 'Unauthorised' } });
        }

        function error(message) {
            return throwError({ status: 400, error: { message } });
        }
    }
}

export let fakeBackendProvider = {
    // use fake backend in place of Http service for backend-less development
    provide: HTTP_INTERCEPTORS,
    useClass: FakeBackendInterceptor,
    multi: true
};
 

Angular 7 JWT Interceptor

Path: /src/app/_helpers/jwt.interceptor.ts

The JWT Interceptor intercepts http requests from the application to add a JWT auth token to the Authorization header if the user is logged in.

It’s implemented using the HttpInterceptor class that was introduced in Angular 4.3 as part of the new HttpClientModule. By extending the HttpInterceptor class you can create a custom interceptor to modify http requests before they get sent to the server.

Http interceptors are added to the request pipeline in the providers section of the app.module.ts file.

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';

import { AuthenticationService } from '@/_services';

@Injectable()
export class JwtInterceptor implements HttpInterceptor {
    constructor(private authenticationService: AuthenticationService) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // add authorization header with jwt token if available
        let currentUser = this.authenticationService.currentUserValue;
        if (currentUser && currentUser.token) {
            request = request.clone({
                setHeaders: {
                    Authorization: `Bearer ${currentUser.token}`
                }
            });
        }

        return next.handle(request);
    }
}
 

Angular 7 User Model

Path: /src/app/_models/user.ts

The user model is a small class that defines the properties of a user.

export class User {
    id: number;
    username: string;
    password: string;
    firstName: string;
    lastName: string;
    token?: string;
}
 

Angular 7 JWT Authentication Service

Path: /src/app/_services/authentication.service.ts

The JWT authentication service is used to login and logout of the application, to login it posts the users credentials to the api and checks the response for a JWT token, if there is one it means authentication was successful so the user details are added to local storage with the token. The token is used by the JWT interceptor above to set the authorization header of http requests made to secure api endpoints.

The logged in user details are stored in local storage so the user will stay logged in if they refresh the browser and also between browser sessions until they logout. If you don’t want the user to stay logged in between refreshes or sessions the behaviour could easily be changed by storing user details somewhere less persistent such as session storage which would persist between refreshes but not browser sessions, or in a private variable in the authentication service which would be cleared when the browser is refreshed.

There are two properties exposed by the authentication service for accessing the currently logged in user. The currentUser observable can be used when you want a component to reactively update when a user logs in or out, for example in the app.component.ts so it can show/hide the main nav bar when the user logs in/out. The currentUserValue property can be used when you just want to get the current value of the logged in user but don’t need to reactively update when it changes, for example in the auth.guard.ts which restricts access to routes by checking if the user is currently logged in.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import { User } from '@/_models';

@Injectable({ providedIn: 'root' })
export class AuthenticationService {
    private currentUserSubject: BehaviorSubject<User>;
    public currentUser: Observable<User>;

    constructor(private http: HttpClient) {
        this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('currentUser')));
        this.currentUser = this.currentUserSubject.asObservable();
    }

    public get currentUserValue(): User {
        return this.currentUserSubject.value;
    }

    login(username: string, password: string) {
        return this.http.post<any>(`${config.apiUrl}/users/authenticate`, { username, password })
            .pipe(map(user => {
                // login successful if there's a jwt token in the response
                if (user && user.token) {
                    // store user details and jwt token in local storage to keep user logged in between page refreshes
                    localStorage.setItem('currentUser', JSON.stringify(user));
                    this.currentUserSubject.next(user);
                }

                return user;
            }));
    }

    logout() {
        // remove user from local storage to log user out
        localStorage.removeItem('currentUser');
        this.currentUserSubject.next(null);
    }
}
 

Angular 7 User Service

Path: /src/app/_services/user.service.ts

The user service contains a method for getting all users from the api, I included it to demonstrate accessing a secure api endpoint with the http authorization header set after logging in to the application, the auth header is set with a JWT token with the JWT Interceptor above. The secure endpoint in the example is a fake one implemented in the fake backend provider above.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { User } from '@/_models';

@Injectable({ providedIn: 'root' })
export class UserService {
    constructor(private http: HttpClient) { }

    getAll() {
        return this.http.get<User[]>(`${config.apiUrl}/users`);
    }
}
 

Angular 7 Home Component Template

Path: /src/app/home/home.component.html

The home component template contains html and angular 7 template syntax for displaying a simple welcome message and a list of users from a secure api endpoint.

<h1>Home</h1>
<p>You're logged in with Angular 7 & JWT!!</p>
<div>
    Users from secure api end point:
    <ul>
        <li *ngFor="let user of users">{{user.firstName}} {{user.lastName}}</li>
    </ul>
</div>
 

Angular 7 Home Component

Path: /src/app/home/home.component.ts

The home component defines an angular 7 component that gets all users from the user service and makes them available to the template via a users array property.

import { Component } from '@angular/core';
import { first } from 'rxjs/operators';

import { User } from '@/_models';
import { UserService, AuthenticationService } from '@/_services';

@Component({ templateUrl: 'home.component.html' })
export class HomeComponent {
    users: User[] = [];

    constructor(private userService: UserService) { }

    ngOnInit() {
        this.userService.getAll().pipe(first()).subscribe(users => {
            this.users = users;
        });
    }
}
 

Angular 7 Login Component Template

Path: /src/app/login/login.component.html

The login component template contains a login form with username and password fields. It displays validation messages for invalid fields when the submit button is clicked. The form submit event is bound to the onSubmit() method of the login component.

The component uses reactive form validation to validate the input fields, for more information about angular reactive form validation check out Angular 7 – Reactive Forms Validation Example.

<div class="alert alert-info">
    Username: test<br />
    Password: test
</div>
<h2>Login</h2>
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
    <div class="form-group">
        <label for="username">Username</label>
        <input type="text" formControlName="username" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.username.errors }" />
        <div *ngIf="submitted && f.username.errors" class="invalid-feedback">
            <div *ngIf="f.username.errors.required">Username is required</div>
        </div>
    </div>
    <div class="form-group">
        <label for="password">Password</label>
        <input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.password.errors }" />
        <div *ngIf="submitted && f.password.errors" class="invalid-feedback">
            <div *ngIf="f.password.errors.required">Password is required</div>
        </div>
    </div>
    <div class="form-group">
        <button [disabled]="loading" class="btn btn-primary">Login</button>
        <img *ngIf="loading" class="pl-2" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
    </div>
    <div *ngIf="error" class="alert alert-danger">{{error}}</div>
</form>
 

Angular 7 Login Component

Path: /src/app/login/login.component.ts

The login component uses the authentication service to login and logout of the application. It automatically logs the user out when it initializes (ngOnInit) so the login page can also be used to logout.

The loginForm: FormGroup object defines the form controls and validators, and is used to access data entered into the form. The FormGroup is part of the Angular Reactive Forms module and is bound to the login template above with the [formGroup]="loginForm" directive.

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { first } from 'rxjs/operators';

import { AuthenticationService } from '@/_services';

@Component({ templateUrl: 'login.component.html' })
export class LoginComponent implements OnInit {
    loginForm: FormGroup;
    loading = false;
    submitted = false;
    returnUrl: string;
    error = '';

    constructor(
        private formBuilder: FormBuilder,
        private route: ActivatedRoute,
        private router: Router,
        private authenticationService: AuthenticationService
    ) { }

    ngOnInit() {
        this.loginForm = this.formBuilder.group({
            username: ['', Validators.required],
            password: ['', Validators.required]
        });

        // reset login status
        this.authenticationService.logout();

        // get return url from route parameters or default to '/'
        this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
    }

    // convenience getter for easy access to form fields
    get f() { return this.loginForm.controls; }

    onSubmit() {
        this.submitted = true;

        // stop here if form is invalid
        if (this.loginForm.invalid) {
            return;
        }

        this.loading = true;
        this.authenticationService.login(this.f.username.value, this.f.password.value)
            .pipe(first())
            .subscribe(
                data => {
                    this.router.navigate([this.returnUrl]);
                },
                error => {
                    this.error = error;
                    this.loading = false;
                });
    }
}
 

Angular 7 App Component Template

Path: /src/app/app.component.html

The app component template is the root component template of the application, it contains the main nav bar which is only displayed for authenticated users, and a router-outlet directive for displaying the contents of each view based on the current route / path.

<!-- nav -->
<nav class="navbar navbar-expand navbar-dark bg-dark" *ngIf="currentUser">
    <div class="navbar-nav">
        <a class="nav-item nav-link" routerLink="/">Home</a>
        <a class="nav-item nav-link" (click)="logout()">Logout</a>
    </div>
</nav>

<!-- main app container -->
<div class="jumbotron">
    <div class="container">
        <div class="row">
            <div class="col-md-6 offset-md-3">
                <router-outlet></router-outlet>
            </div>
        </div>
    </div>
</div>
 

Angular 7 App Component

Path: /src/app/app.component.ts

The app component is the root component of the application, it defines the root tag of the app as <app></app> with the selector property of the @Component() decorator.

It subscribes to the currentUser observable in the authentication service so it can reactively show/hide the main navigation bar when the user logs in/out of the application. I didn’t worry about unsubscribing from the observable here because it’s the root component of the application, the only time the component will be destroyed is when the application is closed which would destroy any subscriptions as well.

The app component contains a logout() method which is called from the logout link in the main nav bar above to log the user out and redirect them to the login page.

import { Component } from '@angular/core';
import { Router } from '@angular/router';

import { AuthenticationService } from './_services';
import { User } from './_models';

@Component({ selector: 'app', templateUrl: 'app.component.html' })
export class AppComponent {
    currentUser: User;

    constructor(
        private router: Router,
        private authenticationService: AuthenticationService
    ) {
        this.authenticationService.currentUser.subscribe(x => this.currentUser = x);
    }

    logout() {
        this.authenticationService.logout();
        this.router.navigate(['/login']);
    }
}
 

Angular 7 App Module

Path: /src/app/app.module.ts

The app module defines the root module of the application along with metadata about the module. For more info about angular 7 modules check out this page on the official docs site.

This is where the fake backend provider is added to the application, to switch to a real backend simply remove the providers located below the comment // provider used to create fake backend.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

// used to create fake backend
import { fakeBackendProvider } from './_helpers';

import { AppComponent } from './app.component';
import { routing } from './app.routing';

import { JwtInterceptor, ErrorInterceptor } from './_helpers';
import { HomeComponent } from './home';
import { LoginComponent } from './login';

@NgModule({
    imports: [
        BrowserModule,
        ReactiveFormsModule,
        HttpClientModule,
        routing
    ],
    declarations: [
        AppComponent,
        HomeComponent,
        LoginComponent
    ],
    providers: [
        { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
        { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },

        // provider used to create fake backend
        fakeBackendProvider
    ],
    bootstrap: [AppComponent]
})

export class AppModule { }
 

Angular 7 App Routing

Path: /src/app/app.routing.ts

The app routing file defines the routes of the application, each route contains a path and associated component. The home route is secured by passing the AuthGuard to the canActivate property of the route.

import { Routes, RouterModule } from '@angular/router';

import { HomeComponent } from './home';
import { LoginComponent } from './login';
import { AuthGuard } from './_guards';

const appRoutes: Routes = [
    {
        path: '',
        component: HomeComponent,
        canActivate: [AuthGuard]
    },
    {
        path: 'login',
        component: LoginComponent
    },

    // otherwise redirect to home
    { path: '**', redirectTo: '' }
];

export const routing = RouterModule.forRoot(appRoutes);
 

Angular 7 Main Index Html File

Path: /src/index.html

The main index.html file is the initial page loaded by the browser that kicks everything off. Webpack bundles all of the javascript files together and injects them into the body of the index.html page so the scripts get loaded and executed by the browser.

<!DOCTYPE html>
<html>
<head>
    <base href="/" />
    <title>Angular 7 - JWT Authentication Tutorial & Example</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- bootstrap css -->
    <link href="//netdna.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" />

    <style>
        a { cursor: pointer }
    </style>
</head>
<body>
    <app>Loading...</app>
</body>
</html>
 

Angular 7 Main (Bootstrap) File

Path: /src/main.ts

The main file is the entry point used by angular to launch and bootstrap the application.

import './polyfills';

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
 

Angular 7 Polyfills

Path: /src/polyfills.ts

Some features used by Angular 7 are not yet supported natively by all major browsers, polyfills are used to add support for features where necessary so your Angular 7 application works across all major browsers.

import 'core-js/features/reflect';
import 'zone.js/dist/zone';
 

Angular 7 Custom Typings File

Path: /src/typings.d.ts

A custom typings file is used to declare types that are created outside of your angular application, so the TypeScript compiler is aware of them and doesn’t give you errors about unknown types. This typings file contains a declaration for the global config object that is created by webpack (see webpack.config.js below).

// so the typescript compiler doesn't complain about the global config object
declare var config: any;
 

npm package.json

Path: /package.json

The package.json file contains project configuration information including package dependencies which get installed when you run npm install. Full documentation is available on the npm docs website.

{
    "name": "angular-7-jwt-authentication-example",
    "version": "1.0.0",
    "repository": {
        "type": "git",
        "url": "https://github.com/cornflourblue/angular-7-jwt-authentication-example.git"
    },
    "scripts": {
        "build": "webpack --mode production",
        "start": "webpack-dev-server --mode development --open"
    },
    "license": "MIT",
    "dependencies": {
        "@angular/common": "^7.0.1",
        "@angular/compiler": "^7.0.1",
        "@angular/core": "^7.0.1",
        "@angular/forms": "^7.0.1",
        "@angular/platform-browser": "^7.0.1",
        "@angular/platform-browser-dynamic": "^7.0.1",
        "@angular/router": "^7.0.1",
        "core-js": "^3.0.1",
        "rxjs": "^6.3.3",
        "zone.js": "^0.9.1"
    },
    "devDependencies": {
        "@types/node": "^12.0.0",
        "angular2-template-loader": "^0.6.2",
        "html-webpack-plugin": "^3.2.0",
        "raw-loader": "^1.0.0",
        "ts-loader": "^5.2.2",
        "typescript": "^3.1.3",
        "webpack": "^4.24.0",
        "webpack-cli": "^3.1.2",
        "webpack-dev-server": "^3.1.10"
    }
}
 

TypeScript tsconfig.json

Path: /tsconfig.json

The tsconfig.json file configures how the TypeScript compiler will convert TypeScript into JavaScript that is understood by the browser. More information is available on the TypeScript docs.

{
    "compilerOptions": {
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "lib": [
            "es2015",
            "dom"
        ],
        "module": "commonjs",
        "moduleResolution": "node",
        "noImplicitAny": false,
        "sourceMap": true,
        "suppressImplicitAnyIndexErrors": true,
        "target": "es5",
        "baseUrl": "src",
        "paths": {
            "@/*": [
                "app/*"
            ]
        }
    }
}
 

Webpack 4 Config

Path: /webpack.config.js

Webpack 4 is used to compile and bundle all the project files so they’re ready to be loaded into a browser, it does this with the help of loaders and plugins that are configured in the webpack.config.js file. For more info about webpack check out the webpack docs.

This is a minimal webpack.config.js for bundling an Angular 7 application, it compiles TypeScript files using ts-loader, loads angular templates with raw-loader, and injects the bundled scripts into the body of the index.html page using the HtmlWebpackPlugin. It also defines a global config object with the plugin webpack.DefinePlugin.

A path alias ‘@’ is configured in the webpack.config.js and the tsconfig.json that maps to the ‘/src/app’ directory. This allows imports to be relative to the ‘/src/app’ folder by prefixing the import path with ‘@’, removing the need to use long relative paths like import MyComponent from '../../../MyComponent'.

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
    entry: './src/main.ts',
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: ['ts-loader', 'angular2-template-loader'],
                exclude: /node_modules/
            },
            {
                test: /\.(html|css)$/,
                loader: 'raw-loader'
            },
        ]
    },
    resolve: {
        extensions: ['.ts', '.js'],
        alias: {
            '@': path.resolve(__dirname, 'src/app/'),
        }
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'index.html',
            inject: 'body'
        }),
        new webpack.DefinePlugin({
            // global app config object
            config: JSON.stringify({
                apiUrl: 'http://localhost:4000'
            })
        })
    ],
    optimization: {
        splitChunks: {
            chunks: 'all',
        },
        runtimeChunk: true
    },
    devServer: {
        historyApiFallback: true
    }
};
Posted in Knowledge, Problem solving, Programming, Uncategorized | Leave a comment

What are Micro Frontends?

From: https://micro-frontends.org/

The term Micro Frontends first came up in ThoughtWorks Technology Radar at the end of 2016. It extends the concepts of micro services to the frontend world. The current trend is to build a feature-rich and powerful browser application, aka single page app, which sits on top of a micro service architecture. Over time the frontend layer, often developed by a separate team, grows and gets more difficult to maintain. That’s what we call a Frontend Monolith.

The idea behind Micro Frontends is to think about a website or web app as a composition of features which are owned by independent teams. Each team has a distinct area of business or mission it cares about and specialises in. A team is cross functional and develops its features end-to-end, from database to user interface.

However, this idea is not new, in the past it went by the name of Frontend Integration for Verticalised Systems or Self-contained Systems. But Micro Frontends is clearly a more friendly and less bulky term.

Monolithic Frontends Monolithic Frontends

Organisation in Verticals End-To-End Teams with Micro Frontends

What’s a Modern Web App?

In the introduction I’ve used the phrase “building a modern web app”. Let’s define the assumptions that are connected with this term.

To put this into a broader perspective, Aral Balkan has written a blog post about what he calls the Documents‐to‐Applications Continuum. He comes up with the concept of a sliding scale where a site, built out of static documents, connected via links, is on the left end and a pure behaviour driven, contentless application like an online photo editor is on the right.

If you would position your project on the left side of this spectrum, an integration on webserver level is a good fit. With this model a server collects and concatenates HTML strings from all components that make up the page requested by the user. Updates are done by reloading the page from the server or replacing parts of it via ajax. Gustaf Nilsson Kottehas written a comprehensive article on this topic.

When your user interface has to provide instant feedback, even on unreliable connections, a pure server rendered site is not sufficient anymore. To implement techniques like Optimistic UIor Skeleton Screens you need to be able to also update your UI on the device itself. Google’s term Progressive Web Apps aptly describes the balancing act of being a good citizen of the web (progressive enhancement) while also providing app-like performance. This kind of application is located somewhere around the middle of the site-app-continuum. Here a solely server based solution is not sufficient anymore. We have to move the integration into the browser, and this is the focus of this article.

Core Ideas behind Micro Frontends

  • Be Technology Agnostic
    Each team should be able to choose and upgrade their stack without having to coordinate with other teams. Custom Elements are a great way to hide implementation details while providing a neutral interface to others.
  • Isolate Team Code
    Don’t share a runtime, even if all teams use the same framework. Build independent apps that are self contained. Don’t rely on shared state or global variables.
  • Establish Team Prefixes
    Agree on naming conventions where isolation is not possible yet. Namespace CSS, Events, Local Storage and Cookies to avoid collisions and clarify ownership.
  • Favor Native Browser Features over Custom APIs
    Use Browser Events for communication instead of building a global PubSub system. If you really have to build a cross team API, try keeping it as simple as possible.
  • Build a Resilient Site
    Your feature should be useful, even if JavaScript failed or hasn’t executed yet. Use Universal Rendering and Progressive Enhancement to improve perceived performance.

The DOM is the API

Custom Elements, the interoperability aspect from the Web Components Spec, are a good primitive for integration in the browser. Each team builds their component using their web technology of choice and wraps it inside a Custom Element (e.g. <order-minicart></order-minicart>). The DOM specification of this particular element (tag-name, attributes & events) acts as the contract or public API for other teams. The advantage is that they can use the component and its functionality without having to know the implementation. They just have to be able to interact with the DOM.

But Custom Elements alone are not the solution to all our needs. To address progressive enhancement, universal rendering or routing we need additional pieces of software.

This page is divided into two main areas. First we will discuss Page Composition – how to assemble a page out of components owned by different teams. After that we’ll show examples for implementing clientside Page Transition.

Page Composition

Beside the client- and serverside integration of code written in different frameworks itself, there are a lot of side topics that should be discussed: mechanisms to isolate jsavoid css conflictsload resources as needed, share common resources between teams, handle data fetching and think about good loading states for the user. We’ll go into these topics one step at a time.

The Base Prototype

The product page of this model tractor store will serve as the basis for the following examples.

It features a variant selector to switch between the three different tractor models. On change product image, name, price and recommendations are updated. There is also a buy button, which adds the selected variant to the basket and a mini basket at the top that updates accordingly.

Example 0 - Product Page - Plain JS

try in browser & inspect the code

All HTML is generated client side using plain JavaScript and ES6 Template Strings with no dependencies. The code uses a simple state/markup separation and re-renders the entire HTML client side on every change – no fancy DOM diffing and no universal rendering for now. Also no team separation – the code is written in one js/css file.

Clientside Integration

In this example, the page is split into separate components/fragments owned by three teams. Team Checkout (blue) is now responsible for everything regarding the purchasing process – namely the buy button and mini basketTeam Inspire (green) manages the product recommendations on this page. The page itself is owned by Team Product (red).

Example 1 - Product Page - Composition

try in browser & inspect the code

Team Product decides which functionality is included and where it is positioned in the layout. The page contains information that can be provided by Team Product itself, like the product name, image and the available variants. But it also includes fragments (Custom Elements) from the other teams.

How to Create a Custom Element?

Lets take the buy button as an example. Team Product includes the button simply adding <blue-buy sku="t_porsche"></blue-buy> to the desired position in the markup. For this to work, Team Checkout has to register the element blue-buy on the page.

class BlueBuy extends HTMLElement {
  constructor() {
    super();
    this.innerHTML = `<button type="button">buy for 66,00 €</button>`;
  }
  disconnectedCallback() { ... }
}
window.customElements.define('blue-buy', BlueBuy);

Now every time the browser comes across a new blue-buy tag, the constructor is called. thisis the reference to the root DOM node of the custom element. All properties and methods of a standard DOM element like innerHTML or getAttribute() can be used.

Custom Element in Action

When naming your element the only requirement the spec defines is that the name must include a dash (-) to maintain compatibility with upcoming new HTML tags. In the upcoming examples the naming convention [team_color]-[feature] is used. The team namespace guards against collisions and this way the ownership of a feature becomes obvious, simply by looking at the DOM.

Parent-Child Communication / DOM Modification

When the user selects another tractor in the variant selector, the buy button has to be updated accordingly. To achieve this Team Product can simply remove the existing element from the DOM and insert a new one.

container.innerHTML;
// => <blue-buy sku="t_porsche">...</blue-buy>
container.innerHTML = '<blue-buy sku="t_fendt"></blue-buy>';

The disconnectedCallback of the old element gets invoked synchronously to provide the element with the chance to clean up things like event listeners. After that the constructor of the newly created t_fendt element is called.

Another more performant option is to just update the sku attribute on the existing element.

document.querySelector('blue-buy').setAttribute('sku', 't_fendt');

If Team Product used a templating engine that features DOM diffing, like React, this would be done by the algorithm automatically.

Custom Element Attribute Change

To support this the Custom Element can implement the attributeChangedCallback and specify a list of observedAttributes for which this callback should be triggered.

const prices = {
  t_porsche: '66,00 €',
  t_fendt: '54,00 €',
  t_eicher: '58,00 €',
};

class BlueBuy extends HTMLElement {
  static get observedAttributes() {
    return ['sku'];
  }
  constructor() {
    super();
    this.render();
  }
  render() {
    const sku = this.getAttribute('sku');
    const price = prices[sku];
    this.innerHTML = `<button type="button">buy for ${price}</button>`;
  }
  attributeChangedCallback(attr, oldValue, newValue) {
    this.render();
  }
  disconnectedCallback() {...}
}
window.customElements.define('blue-buy', BlueBuy);

To avoid duplication a render() method is introduced which is called from constructor and attributeChangedCallback. This method collects needed data and innerHTML’s the new markup. When deciding to go with a more sophisticated templating engine or framework inside the Custom Element, this is the place where its initialisation code would go.

Browser Support

The above example uses the Custom Element V1 Spec which is currently supported in Chrome, Safari and Opera. But with document-register-element a lightweight and battle-tested polyfill is available to make this work in all browsers. Under the hood, it uses the widely supported Mutation Observer API, so there is no hacky DOM tree watching going on in the background.

Framework Compatibility

Because Custom Elements are a web standard, all major JavaScript frameworks like Angular, React, Preact, Vue or Hyperapp support them. But when you get into the details, there are still a few implementation problems in some frameworks. At Custom Elements Everywhere Rob Dodson has put together a compatibility test suite that highlights unresolved issues.

Child-Parent or Siblings Communication / DOM Events

But passing down attributes is not sufficient for all interactions. In our example the mini basket should refresh when the user performs a click on the buy button.

Both fragments are owned by Team Checkout (blue), so they could build some kind of internal JavaScript API that lets the mini basket know when the button was pressed. But this would require the component instances to know each other and would also be an isolation violation.

A cleaner way is to use a PubSub mechanism, where a component can publish a message and other components can subscribe to specific topics. Luckily browsers have this feature built-in. This is exactly how browser events like clickselect or mouseover work. In addition to native events there is also the possibility to create higher level events with new CustomEvent(...). Events are always tied to the DOM node they were created/dispatched on. Most native events also feature bubbling. This makes it possible to listen for all events on a specific sub-tree of the DOM. If you want to listen to all events on the page, attach the event listener to the window element. Here is how the creation of the blue:basket:changed-event looks in the example:

class BlueBuy extends HTMLElement {
  [...]
  connectedCallback() {
    [...]
    this.render();
    this.firstChild.addEventListener('click', this.addToCart);
  }
  addToCart() {
    // maybe talk to an api
    this.dispatchEvent(new CustomEvent('blue:basket:changed', {
      bubbles: true,
    }));
  }
  render() {
    this.innerHTML = `<button type="button">buy</button>`;
  }
  disconnectedCallback() {
    this.firstChild.removeEventListener('click', this.addToCart);
  }
}

The mini basket can now subscribe to this event on window and get notified when it should refresh its data.

class BlueBasket extends HTMLElement {
  connectedCallback() {
    [...]
    window.addEventListener('blue:basket:changed', this.refresh);
  }
  refresh() {
    // fetch new data and render it
  }
  disconnectedCallback() {
    window.removeEventListener('blue:basket:changed', this.refresh);
  }
}

With this approach the mini basket fragment adds a listener to a DOM element which is outside its scope (window). This should be ok for many applications, but if you are uncomfortable with this you could also implement an approach where the page itself (Team Product) listens to the event and notifies the mini basket by calling refresh() on the DOM element.

// page.js
const $ = document.getElementsByTagName;

$('blue-buy')[0].addEventListener('blue:basket:changed', function() {
  $('blue-basket')[0].refresh();
});

Imperatively calling DOM methods is quite uncommon, but can be found in video element apifor example. If possible the use of the declarative approach (attribute change) should be preferred.

Serverside Rendering / Universal Rendering

Custom Elements are great for integrating components inside the browser. But when building a site that is accessible on the web, chances are that initial load performance matters and users will see a white screen until all js frameworks are downloaded and executed. Additionally, it’s good to think about what happens to the site if the JavaScript fails or is blocked. Jeremy Keith explains the importance in his ebook/podcast Resilient Web Design. Therefore the ability to render the core content on the server is key. Sadly the web component spec does not talk about server rendering at all. No JavaScript, no Custom Elements 😦

Custom Elements + Server Side Includes = ❤️

To make server rendering work, the previous example is refactored. Each team has their own express server and the render() method of the Custom Element is also accessible via url.

$ curl http://127.0.0.1:3000/blue-buy?sku=t_porsche
<button type="button">buy for 66,00 €</button>

The Custom Element tag name is used as the path name – attributes become query parameters. Now there is a way to server-render the content of every component. In combination with the <blue-buy>-Custom Elements something that is quite close to a Universal Web Component is achieved:

<blue-buy sku="t_porsche">
  <!--#include virtual="/blue-buy?sku=t_porsche" -->
</blue-buy>

The #include comment is part of Server Side Includes, which is a feature that is available in most web servers. Yes, it’s the same technique used back in the days to embed the current date on our web sites. There are also a few alternative techniques like ESInodesicompoxure and tailor, but for our projects SSI has proven itself as a simple and incredibly stable solution.

The #include comment is replaced with the response of /blue-buy?sku=t_porsche before the web server sends the complete page to the browser. The configuration in nginx looks like this:

upstream team_blue {
  server team_blue:3001;
}
upstream team_green {
  server team_green:3002;
}
upstream team_red {
  server team_red:3003;
}

server {
  listen 3000;
  ssi on;

  location /blue {
    proxy_pass  http://team_blue;
  }
  location /green {
    proxy_pass  http://team_green;
  }
  location /red {
    proxy_pass  http://team_red;
  }
  location / {
    proxy_pass  http://team_red;
  }
}

The directive ssi: on; enables the SSI feature and an upstream and location block is added for every team to ensure that all urls which start with /blue will be routed to the correct application (team_blue:3001). In addition the / route is mapped to team red, which is controlling the homepage / product page.

This animation shows the tractor store in a browser which has JavaScript disabled.

Serverside Rendering - Disabled JavaScript

inspect the code

The variant selection buttons now are actual links and every click leads to a reload of the page. The terminal on the right illustrates the process of how a request for a page is routed to team red, which controls the product page and after that the markup is supplemented by the fragments from team blue and green.

When switching JavaScript back on, only the server log messages for the first request will be visible. All subsequent tractor changes are handled client side, just like in the first example. In a later example the product data will be extracted from the JavaScript and loaded via a REST api as needed.

You can play with this sample code on your local machine. Only Docker Compose needs to be installed.

git clone https://github.com/neuland/micro-frontends.git
cd micro-frontends/2-composition-universal
docker-compose up --build

Docker then starts the nginx on port 3000 and builds the node.js image for each team. When you open http://127.0.0.1:3000/ in your browser you should see a red tractor. The combined log of docker-compose makes it easy to see what is going on in the network. Sadly there is no way to control the output color, so you have to endure the fact that team blue might be highlighted in green 🙂

The src files are mapped into the individual containers and the node application will restart when you make a code change. Changing the nginx.conf requires a restart of docker-composein order to have an effect. So feel free to fiddle around and give feedback.

Data Fetching & Loading States

A downside of the SSI/ESI approach is, that the slowest fragment determines the response time of the whole page. So it’s good when the response of a fragment can be cached. For fragments that are expensive to produce and hard to cache it’s often a good idea to exclude them from the initial render. They can be loaded asynchronously in the browser. In our example the green-recos fragment, that shows personalized recommendations is a candidate for this.

One possible solution would be that team red just skips the SSI Include.

Before

<green-recos sku="t_porsche">
  <!--#include virtual="/green-recos?sku=t_porsche" -->
</green-recos>

After

<green-recos sku="t_porsche"></green-recos>

Important Side-note: Custom Elements cannot be self-closing, so writing <green-recos sku="t_porsche" /> would not work correctly.

Reflow

The rendering only takes place in the browser. But, as can be seen in the animation, this change has now introduced a substantial reflow of the page. The recommendation area is initially blank. Team greens JavaScript is loaded and executed. The API call for fetching the personalized recommendation is made. The recommendation markup is rendered and the associated images are requested. The fragment now needs more space and pushes the layout of the page.

There are different options to avoid an annoying reflow like this. Team red, which controls the page, could fixate the recommendation containers height. On a responsive website its often tricky to determine the height, because it could differ for different screen sizes. But the more important issue is, that this kind of inter-team agreement creates a tight couplingbetween team red and green. If team green wants to introduce an additional sub-headline in the reco element, it would have to coordinate with team red on the new height. Both teams would have to rollout their changes simultaneously to avoid a broken layout.

A better way is to use a technique called Skeleton Screens. Team red leaves the green-recosSSI Include in the markup. In addition team green changes the server-side render methodof its fragment so that it produces a schematic version of the content. The skeleton markup can reuse parts of the real content’s layout styles. This way it reserves the needed space and the fill-in of the actual content does not lead to a jump.

Skeleton Screen

Skeleton screens are also very useful for client rendering. When your custom element is inserted into the DOM due to a user action it could instantly render the skeleton until the data it needs from the server has arrived.

Even on an attribute change like for the variant select you can decide to switch to skeleton view until the new data arrives. This ways the user gets an indication that something is going on in the fragment. But when your endpoint responds quickly a short skeleton flickerbetween the old and new data could also be annoying. Preserving the old data or using intelligent timeouts can help. So use this technique wisely and try to get user feedback.

to be continued soon…

watch the Github Repo to get notified

Additional Resources

Posted in Education and Training, Integration, Knowledge, Problem solving, Programming, Uncategorized | Leave a comment

Autowiring :expected at least 1 bean which qualifies as autowire candidate for this dependency

https://stackoverflow.com/questions/44149690/autowiring-expected-at-least-1-bean-which-qualifies-as-autowire-candidate-for-t?rq=1

ApplicationConfig file:

@Configuration
@ComponentScan("my.basepackage.*")
@EnableJpaRepositories(basePackages = {"my.basepackage.*"})
@EntityScan("my.basepackage.*")
@EnableAutoConfiguration
Posted in Java, Knowledge, Software architecture, Uncategorized | Leave a comment

IoT Asset Management Using Graph Database Modeling

The Challenge

Power grid systems are considered an integral part of modern society. Their robustness and efficiency not only impact our daily lives, but also influence economy, politics, and the global environment. Power grids continually evolve over time to accommodate and promote societal developments; currently, transmission grids are going through a transition from relying on traditional centralized utility-based power generation to integrating distributed energy resources (DER) such as photovoltaic (PV) systems, distributed energy storage (DES) such as battery systems, and demand response (DR). With the additional push for the integration of smart Internet-of-Things (IoT) devices, the smart grid is continually evolving into an increasingly interconnected cyber-physical system (CPS) that requires a paradigm shift in both its planning and operation. The use of graph databases as a sophisticated tool for modeling the connection between system components– transformers, distribution lines, DER, DES, IoT devices, grid operator, electricity consumers, etc.–can aid in managing the rapidly evolving smart grid.

The Solution

To address the demand of managing the integration of connected devices and enabling new business models from the heavily interconnected systems, current architectural reference models were considered and components of each synthesized into a software stack for smart application development. This work lends its implementation approach to the utility of graph theory in modeling complex systems, and implements a graph database for managing and maintaining connected components that emphasize each component’s virtual and physical connectivity, its technical functionalities, and its state. The graph database microservice is then integrated with a highly available web framework and communication broker service in a multi-layered software framework to integrate Internet-of-Things devices and make services available over the web. The framework’s–and its respective components’–efficacy has been demonstrated in a simplified use case for modeling, connecting, and controlling interconnected homes in a modern smart grid and abstracting transactional device data for new business models, such as demand response ancillary services.

FEATURED PHOTOS

LAYERED SOFTWARE DESIGN APPROACH

NEO4J GRAPH COMPONENTS

NEO4J CYPHER QUERIES ARE BUILDT ON RELATIONSHIPS

TRANSACTIONAL STATES OF THE GRID CAN BE QUERIED AT EASE

QUERIES BUILT ON RELATIONSHIPS ENABLE NEW ENERGY INFORMATIC ANALYSES, SUCH AS THE ONE ABOVE FOR DEMAND RESPONSE

MQTT TOPICS ARE FLEXIBLE AND EASE PUB/SUB COMMUNICATION

WEB INTERFACE FOR SENDING MQTT COMMANDS

SMART GRID SUBGRAPH SHOWING RELATIONSHIPS BETWEEN VARIOUS ACTORS.

NODE-RED PROVIDES GREAT TOOLS FOR RAPID IOT DEVELOPMENT AND DEVICE SIMULATION

NODE-RED FLOW OF A GATEWAY FOR CONTROLING A HOME ENERGY MANAGEMENT SYSTEM.

Posted in ASP.NET MVC, Business Metrics, Business Model, Problem solving, Programming, Software architecture, Uncategorized | Leave a comment

How to start using Entity Framework 6 with MySQL databases

To start using Entity Framework 6 and Visual Studio 2013 is necessary to install MySQL for Visual Studio 1.1.1 Beta and MySQL Connector/Net 6.8.1 Beta

MySQL for Visual Studio 1.1.1 Beta can be downloaded with the following link:
https://cdn.mysql.com/Downloads/MySQLInstaller/mysql-visualstudio-plugin-1.1.1.msi

MySQL Connector/Net 6.8.1 Beta
http://dev.mysql.com/downloads/connector/net/

To start working with VS 2013 and EF 6

1- Install the MySQL for Visual Studio 1.1.1
2- Install the Connector/Net 6.8.1 product.
3- To work with Database first please do the following
a. Add the reference for the new assembly called MySql.Data.Entity.EF6 and copy it to the bin forlder of your application. (important)
b. Add the provider to your app/web config file on the providers for Entity Framework section with the following line:
<provider invariantName=”MySql.Data.MySqlClient” type=”MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6″></provider>
c. Before you run the Wizard compile your application so the new changes are applied.
4- To work with Model First please do the following
a. Add the reference for the new assembly called MySql.Data.Entity.EF6 and copy it to the bin forlder of your application.
b. Add the ADO.Net Entity Model new or existing.
c. Select the T4 template corresponding to MySQL (SSDLToMySQL)
d. Right click on the model and then select Generate Script to Create Database. (A MySQL script should be generated for you to create your database).

Source: https://forums.mysql.com/read.php?174,601264,601264

Posted in ASP.NET MVC, C#, Problem solving, Programming, Uncategorized | Leave a comment

How to resolve “Cannot create JDBC driver of class ‘com.mysql.jdbc.Driver’ for connect URL”

Firstly I want to say that i checked all answers at stackoverflow, and i can’t fix this bug! Help me please! I spend a lot of time, but no result. I’m trying to create connection pool using Tomcat8. I have an exception:

java.sql.SQLException: Cannot create JDBC driver of class ‘com.mysql.jdbc.Driver’ for connect URL ‘jdbc:mysql:/localhost:3306/autopark’ at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createConnectionFactory(BasicDataSource.java:2160) at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2032) at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1532) at ua.khpi.shapoval.db.DbConnector.init(DbConnector.java:31) at ua.khpi.shapoval.db.DbContextListner.contextInitialized(DbContextListner.java:48) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4842) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1407) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1397) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.sql.SQLException: No suitable driver at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createConnectionFactory(BasicDataSource.java:2151) … 13 more

DbConnector.class

public class DbConnector {
    private static Logger log = Logger.getLogger(DbConnector.class.getName());
    private static DataSource dataSource;
    private static Connection connection;

    public static void init() throws ServletException, SQLException, NamingException, ClassNotFoundException {

        Context initCtx = new InitialContext();

        Context envCtx = (Context) initCtx.lookup("java:comp/env/");

        DataSource ds = (DataSource) envCtx.lookup("jdbc/autopark");
        System.out.println(ds.getConnection());
    }

    public static Connection getConnection() throws SQLException {

        return dataSource.getConnection();
    }

}

context.xml that located in META-INF folder

    <?xml version="1.0" encoding="UTF-8"?>
<Context crossContext="true" reloadable="true">
    <Resource name="jdbc/autopark" auth="Container" type="javax.sql.DataSource"
        username="root" password="161acid161" driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql:/localhost:3306/autopark" maxActive="15" maxIdle="3" />
    <ResourceLink name="jdbc/autopark" global="jdbc/autopark"

        type="javax.sql.DataSource" />

</Context>

web.xml file

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    id="WebApp_ID" version="3.1">
    <display-name>Autostation</display-name>
    <welcome-file-list>

        <welcome-file>index.jsp</welcome-file>

    </welcome-file-list>


        <resource-ref>

            <description>Db</description>

            <res-ref-name>jdbc/autopark</res-ref-name>

            <res-type>javax.sql.DataSource</res-type>

            <res-auth>Container</res-auth>

        </resource-ref>


    <listener>
        <listener-class>ua.khpi.shapoval.db.DbContextListner</listener-class>
    </listener>
</web-app>

Content of my tomcat/lib directory and my project structure. enter image description here

enter image description here

The JDBC URL is not correct, indeed you have a missing slash so try this:

jdbc:mysql://localhost:3306/autopark

If you check well the real error is No suitable driver which means that it cannot find any JDBC driver that supports the provided URL.

Posted in Education and Training, Java, Knowledge, Problem solving, Programming, Uncategorized | Leave a comment