hmm: Angular 8: Nach Login wird mir die neue Componente auf dem Login Bildschirm angezeigt

Hi Leute,

ich habe in Angular 8 folgende Login Komponente (Ist nur ein Test, das Hardcodet Login kommt später weg), welche unter / angezeigt wird:

export class HomeComponent implements OnInit {

  model: ILogin = { userid: "admin", password: "admin@123" }
  loginForm: FormGroup;
  message: string;
  returnUrl: string;
  constructor(
    private formBuilder: FormBuilder,
    private router: Router,
    private authService: AuthService
  ) { }

  ngOnInit() {
    this.loginForm = this.formBuilder.group({
      userid: ['', Validators.required],
      password: ['', Validators.required]
    });
    this.returnUrl = '/dashboard';
    this.authService.logout();
  }

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


  login() {

    // stop here if form is invalid
    if (this.loginForm.invalid) {
      return;
    }
    else {
      if (this.f.userid.value == this.model.userid && this.f.password.value == this.model.password) {
        console.log("Login successful");
        //this.authService.authLogin(this.model);
        localStorage.setItem('isLoggedIn', "true");
        localStorage.setItem('token', this.f.userid.value);
        this.router.navigate([this.returnUrl]);
      }
      else {
        this.message = "Please check your userid and password";
      }
    }
  }

}

Nach Login soll folgende Komponente angezeigt werden:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../services/auth.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {

  id: string;

  constructor(private router: Router, private authService: AuthService) { }

  ngOnInit() {
    this.id = localStorage.getItem('token');
    //console.log(this.id);
  }

  logout() {
    console.log('logout');
    this.authService.logout();
    this.router.navigate(['/']);
  }

}

Login Managment:

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

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

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    if (this.isLoggedIn()) {
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }

  public isLoggedIn(): boolean {
    let status = false;
    if (localStorage.getItem('isLoggedIn') === 'true') {
      status = true;
    } else {
      status = false;
    }
    return status;
  }
}

Hier mein Routing:

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

import {DashboardComponent} from "./dashboard/dashboard.component";
import {AuthGuard} from "./guards/auth.guard";
import {HomeComponent} from "./home/home.component";

const routes: Routes = [
  { path: 'dashboard', component: DashboardComponent, canActivate : [AuthGuard] }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [{provide: APP_BASE_HREF, useValue : '/' }]
})
export class AppRoutingModule { }

Problem: Nach erfolgreichem Login lande ich zwar unter der URl /dashboard, aber leiderist die HomeKomponente mit dem Login dort noch sichtbar. Wie ändere ich das?

akzeptierte Antworten

  1. Tach!

    ich habe in Angular 8

    Mach aus der Problemstellung bitte ein Stackblitz-Projekt, damit man das nachvollziehen kann.

    So hab ich nur allgemeine Anmerkungen.

    Code ins ngOnInit() musst du nur dann schreiben, wenn du Inhalte von @Input() verarbeiten musst. Anderer Initialisierungscode kann bereits im Constructor laufen. Für Initialisierungen allgemeiner Art ist der ja zuständig. ngOnInit() ist nur ein spezieller Hook im Lifecycle. Vor allem betrifft das in der HomeComponent die Initialisierung des Formulars und das Zuweisen der returnUrl. Letzteres kann auch gleich bei der Deklaration erfolgen, so wie du das für model gemacht hast.

    Im AuthGuard:

      public isLoggedIn(): boolean {
        let status = false;
        if (localStorage.getItem('isLoggedIn') === 'true') {
          status = true;
        } else {
          status = false;
        }
        return status;
      }
    

    Das ist sehr umständlich, hier reicht ein Einzeiler

    return localStorage.getItem('isLoggedIn') == 'true';
    

    Noch besser ist, für den Local-/SessionStorage einen Service zu verwenden, der die Daten nach JSON serialisiert und beim Abfragen wieder Rohformat zurückgibt. Das gibts in vielerlei Ausführung auch fertig, zum Beispiel ngx-webstorage-service.

    Problem: Nach erfolgreichem Login lande ich zwar unter der URl /dashboard, aber leiderist die HomeKomponente mit dem Login dort noch sichtbar. Wie ändere ich das?

    Kann ich nicht nachvollziehen, dafür fehlt zu viel Code.

    dedlfix.

    1. danke.

      hier habe ich ein Stackblitz Project angelegt:

      https://github.com/ChristopherWy/angular-chttkc

      1. Tach!

        hier habe ich ein Stackblitz Project angelegt:

        https://github.com/ChristopherWy/angular-chttkc

        GitHub brauch ich nicht, aber da ist ja das StackBlitz-Projekt verlinkt. Nun seh ich auch das Problem.

        Du hast die HomeComponent zum Grundgerüst der Anwendung gemacht. An deren Ende im HTML-Template befindet sich <router-outlet></router-outlet>. Das heißt, dass die HomeComponent immer geladen ist, und das was der Router liefert unten angefügt wird. Du müsstest es so umstellen, dass die im AppModule angegebene Komponente für "bootstrap" nur ein Grundgerüst ist, und der eigentliche Inhalt vom Router geliefert wird. Das heißt auch, dass du eine Route für path: '', pathMatch: 'full' definieren musst, die die HomeComponent liefert, in der dann die Begrüßung enthalten ist. Das Login würde ich in eine eigene Komponente packen, aber zur Not kann das auch in der HomeComponent sein.

        Normalerweise wird vom Scaffolder ja die AppComponent erzeugt und dem bootstrap zugewiesen. Die erfüllt diese Grundgerüst-Aufgabe.

        dedlfix.

        1. danke, hat geklappt.

  2. Hi,

    ich habe 20-30 alte AngularJS Codeschnipsel der folgenden Form:

    (function() {
        'use strict';
    
        angular
            .module('app')
            .factory('ReleaseSearch', ReleaseSearch);
    
        ReleaseSearch.$inject = ['$resource','DateUtils'];
    
        function ReleaseSearch($resource,DateUtils) {
            var resourceUrl =  'rest/ui/releases'
                               + '?:search';
    
            return $resource(resourceUrl, {search : '@search'}, {
                'query': { method: 'GET',
                    transformResponse: function (data) {
                        data = angular.fromJson(data);
                        data.validFrom = DateUtils.convertDate(data.validFrom);
                        return data;
                    },
                    isArray: true}
            });
        }
    })();
    

    Wie schreibe ich in Angular8 JavaScript Module die von anderen Modulen verwendet werden können und die mit den Komponenten interagieren? Ich würde z.b. gerne ein JavaScript Modul schreiben, welches von allen Komponenten angesprochen werden kann.

    Kann ich da einfach nodejs Module in den ts Files imporieren?

    1. Tach!

      Wie schreibe ich in Angular8 JavaScript Module die von anderen Modulen verwendet werden können und die mit den Komponenten interagieren?

      Angular 2 hat ja eine Menge alter Zöpfe von AngularJS abgeschnitten und viele Dinge vereinfacht. Zu klären wäre in dem Fall, welche funktionale Aufgabe dieser Codeteil hat, und welche Teile von Angular 2+ gemäß der neuen Philosophie dafür zuständig sind. Vermutlich wird es wohl ein Service sein.

      Ich würde z.b. gerne ein JavaScript Modul schreiben, welches von allen Komponenten angesprochen werden kann.

      Wenn es auch unabhängig von Angular eingesetzt werden soll, dann erscheint mir das sinnvoll. Wenn es lediglich Geschäftslogik der Anwendung ist, würde ich das gemäß der Angular-Philosophie umsetzen. Ansonsten hast du am Ende vielleicht zwei Teile, den eigentlichen Code und einen Wrapper, der das für den Rest der Angular-Anwendung verfügbar macht.

      Kann ich da einfach nodejs Module in den ts Files imporieren?

      Man kann von TypeScript aus problemlos sämtliche JavaScript-Features und in JavaScript geschriebenen Code verwenden. Es ist nur nicht besonders schön, wenn man die Typsicherheit von TypeScript schwächt, indem man sich untypisierten JavaScript-Code ins Boot holt. Das schränkt auch die Unterstützungsmöglichkeiten einer IDE ein. Man kann zwar Declaration Files erstellen, und so den JavaScript-Code nachträglich typisieren, aber das ist auch nur eine Notlösung, die bei Änderungen immer mitgepflegt werden muss. Wenn es denn etwas sein soll, dass unabhängig von Angular agieren soll, würde ich das auch in TypeScript entwickeln. Die Plain-Old-JavaScript-Welt kommt ja auch mit dem Transpilat problemlos zurecht.

      dedlfix.

      1. danke, dann ersetze ich diese module durch services.

        Kann man mit Angular auch Backendseitig entwickeln? Könnte ich zb einen Angular 8 Restservice bauen?

        1. Tach!

          Kann man mit Angular auch Backendseitig entwickeln? Könnte ich zb einen Angular 8 Restservice bauen?

          Angular ist nicht darauf ausgelegt, serverseitig zu laufen. Es hat keine Funktionalität, die dafür nützlich wäre. Aber du kannst NodeJS serverseitig laufen lassen, und dafür sicher auch TypeScript verwenden. Was serverseitig läuft, ist ja im Prinzip egal, es werden sowieso nur Daten unabhängig von irgendwelchen Programmiersprachen/-umgebungen im Request/Response übertragen.

          dedlfix.