17 Ağustos 2021 Salı

Routing guard

 app.routing.module.ts

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

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

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

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

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }

auth.guard.ts

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

import { AuthenticationService } from '@app/_services';

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

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const user = this.authenticationService.userValue;
        if (user) {
            // logged in so return true
            return true;
        } else {
            // not logged in so redirect to login page with the return url
            this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
            return false;
        }
    }
}

Interceptor example

 app.module.ts

providers: [
    { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }
]

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

import { environment } from '@environments/environment';
import { AuthenticationService } from '@app/_services';

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

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // add auth header with jwt if user is logged in and request is to the api url
        const user = this.authenticationService.userValue;
        const isLoggedIn = user && user.jwtToken;
        const isApiUrl = request.url.startsWith(environment.apiUrl);
        if (isLoggedIn && isApiUrl) {
            request = request.clone({
                setHeaders: { Authorization: `Bearer ${user.jwtToken}` }
            });
        }

        return next.handle(request);
    }
}

Production variables

 environment.ts

export const environment = {
    production: false,
    serviceUrl: "https://localhost:5001"
};

environment.prod.ts

export const environment = {
    production: true,
    serviceUrl: "https://www.site.com"
};

ng build command compiles all project with environment.prod.ts file so if you sure environment.serviceUrl at any point of your code, it will be changed from localhost to site.com...

App Initializer

app.initializer.ts

export function appInitializer(/* authenticationService: AuthenticationService */) {
    return () => new Promise(resolve => {
        console.log("app initialize");
    });
}

app.module.ts

providers: [
    { provide: APP_INITIALIZER, useFactory: appInitializer, multi: true/*, deps: [AuthenticationService]*/ }
],

becareful about the deps and injection parts...

22 Haziran 2021 Salı

Text Ellipsis

text-overflow:ellipsis; only works when the following are true:

The element's width must be constrained in px (pixels). Width in % (percentage) won't work.
The element must have overflow:hidden and white-space:nowrap set.

text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;

9 Haziran 2021 Çarşamba

Angular HttpClient error handling working code

 public load(urlstring = '') {

        if (url) {
            this.url = url;
        }

        this.httpClient.get<T>(this.url)
        .pipe(catchError((erranycaughtObservable<T>): ObservableInput<T=> {
            return throwError(err);
        }))
        .subscribe((data=> {
            this.data = data
            this.onLoad.next(this.data);            
        });
    }

28 Mayıs 2021 Cuma

Can't bind to 'ngIf' since it isn't a known property of 'div'

import { CommonModule } from '@angular/common';  
import { BrowserModule } from '@angular/platform-browser';

 @NgModule({
    imports: [CommonModule],
    declarations: [MyComponent]
  ...
})
class MyComponentModule {}

26 Mayıs 2021 Çarşamba

Angular nginx hosting

 server {

    listen        80;

    server_name   portal-vfabrika.sebittest.com;

    location / {

            root   /home/server/apps/vfabrika-portal;

            index  index.html index.htm;

            try_files $uri $uri/ /index.html;

    }

}

/etc/nginx/sites-available/default dosyasında en sona eklenebilir.

22 Mart 2021 Pazartesi

Angular General Project Requirements

Multiple applications in same project.
Material or Bootstrap layouting support.
i18n multi-language support for static resources.
A well designed folder structure for components, services, etc.
Authentication/authorization support with oidc client.

Create empty project
ng new AppName --createApplication=false --directory=AppName --interactive=false

Add project
ng generate application ProjectName --style=scss --routing=true

 

6 Mart 2021 Cumartesi

Best Practices

Yeni bir font nasıl eklerim?

Angular kendisi de dahil olmak üzere font'ları index.html dosyasından ekliyor. Yeni proje oluşturduğunuzda font import'u ve material icon'ları için link tanımlamasını index.html'de görebilirsiniz.

Örnek routing tanımlaması

const routes: Routes = [
  { path: '', redirectTo: '/designer', pathMatch: 'full' },
  { path: 'login', component: LoginComponent },
  { path: 'dashboard', component: DashboardComponent },
  { path: 'designer', component: DesignerComponent },
  { path: 'logout', component: LogoutComponent }
];