I trying to implements a login system in Angular App, but it redirects to the main view and saves an empty object into Local Storage no meters what I typed into the form, a correct or fake account email and password. It's my first real project and first time to making a login system. Uniformly I don't have permission to show real API here.
The Code:
login.component.html
<div class="content">
<div fxLayout="column" fxLayoutAlign="center center">
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>Dobrodošli!</mat-card-title>
</mat-card-header>
<mat-card-content>
<img class="logo" src="../../assets/dnevnimeni.svg" alt="">
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<mat-form-field>
<input matInput type="email" placeholder="E-Mail" formControlName="email">
<mat-error *nfIf="">Unesite odgovarajući E-Mail</mat-error>
</mat-form-field> <br>
<mat-form-field>
<input matInput type="password" placeholder="Password" formControlName="password">
<mat-error *ngIf="">Unesite validan password</mat-error>
</mat-form-field> <br>
<button mat-stroked-button>Login</button>
</form>
</mat-card-content>
</mat-card>
</div>
</div>
login.component.ts
import { Component, OnInit } from '#angular/core';
import { FormBuilder, Validators, FormGroup } from '#angular/forms';
import { Router } from '#angular/router';
import { AuthService } from '../services/auth.service';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
loginForm: FormGroup;
submitted = false;
returnUrl: string;
error: {};
loginError: string;
constructor(
private fb: FormBuilder,
private router: Router,
private authService: AuthService
) { }
ngOnInit() {
this.loginForm = this.fb.group({
email: ['', Validators.required],
password: ['', Validators.required]
});
this.authService.logout();
}
get email() { return this.loginForm.get('email'); }
get password() { return this.loginForm.get('password'); }
onSubmit() {
this.submitted = true;
this.authService.login( this.email.value, this.password.value).subscribe((data) => {
if (this.authService.isLoggedIn) {
const redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/';
this.router.navigate([redirect]);
} else {
this.loginError = 'email or password is incorrect.';
}
},
error => this.error = error
);
console.log(this.authService.restaurant.email);
}
}
and auth.service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '#angular/common/http';
import { throwError, Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { Restaurant } from '../models/Restaurant';
#Injectable({
providedIn: 'root'
})
export class AuthService {
loginUrl = 'xxxxxxxx';
errorData: {};
restaurant: Restaurant;
constructor(private http: HttpClient) { }
redirectUrl: string;
login(email: string, password: string) {
var postData = "email=" + email + "&password=" + password;
return this.http.post<Restaurant>(this.loginUrl, postData)
.pipe(map(restaurant => {
if (restaurant) {
localStorage.setItem('currentRestaurant', JSON.stringify(restaurant));
}
}),
catchError(this.handleError)
);
}
isLoggedIn() {
if (localStorage.getItem('currentRestaurant')) {
return true;
}
return false;
}
getAuthorizationToken() {
const currentRestaurant = JSON.parse(localStorage.getItem('currentRestaurant'));
return currentRestaurant.token;
}
logout() {
localStorage.removeItem('currentRestaurant');
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong.
console.error(`Backend returned code ${error.status}, ` + `body was: ${error.error}`);
}
// return an observable with a user-facing error message
this.errorData = {
errorTitle: 'Oops! Request for document failed',
errorDesc: 'Something bad happened. Please try again later.'
};
return throwError(this.errorData);
}
}
In the map function you don't return any value and try to transform in object the parameters that sends in the post request;
login(email: string, password: string) {
let postData = {email : email ,password :password};
return this.http.post<Restaurant>(this.loginUrl, postData)
.pipe(map(restaurant => {
if (restaurant) {
localStorage.setItem('currentRestaurant', JSON.stringify(restaurant));
return restaurant;
}
}),
catchError(this.handleError)
);
}
Your post data should be like var postData = {email : email ,password :password} , but you have described get request with query parameters.
Also saving data in observable data stream is bad practice. Each new subscriber triggers execution of this code again
if (restaurant) {
localStorage.setItem('currentRestaurant', JSON.stringify(restaurant));
}
postData should be the object instead of string. also check by console.log in isLoggedIn() method, what data localStorage.getItem('currentRestaurant') returns, if it has a value like "{}" or "null" it will return true in if statement.
isLoggedIn() {
if (localStorage.getItem('currentRestaurant')) {
return true;
}
return false; }
Related
Good morning friends, sorry for the inconvenience I am doing practices to learn and I was doing a login, but the problem is that I am trying to connect it to an api and it does not make the connection, it gives me a super strange error in the login component
Here I attach the login.component
import { Component, } from '#angular/core';
import { AppserviceService } from '../../services/appservice.service';
import { NgForm } from '#angular/forms';
import { AppsResp } from '../../interfaces/interfaces';
import { FormsModule } from '#angular/forms';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
})
export class LoginComponent {
email:string ='';
password:string='';
constructor(public AppserviceService: AppserviceService) { }
login() {
const user = {email: this.email, password: this.password};
this.AppserviceService.login(user).subscribe( data => {
console.log(data);
});
}
}
the error that fits is the following_ "Expected 2 arguments, but got 1.ts(2554)
appservice.service.ts(15, 26): An argument for 'password' was not provided."
Here I attach the app services service, which is where the origin of the error marks me
import { HttpClient } from '#angular/common/http';
import { Injectable, Query } from '#angular/core';
import { Observable } from 'rxjs';
import { AppsResp, Registro } from '../interfaces/interfaces';
#Injectable({
providedIn: 'root'
})
export class AppserviceService {
constructor(private http: HttpClient) { }
login ( email: string, password: string ){
const body = {email,password}
return this.http.post <AppsResp>("http://apitest.e-bango.com/api/auth/login" , body );
}
}
Likewise, I can't find the correct logic to insert the registry component in my service, can you help me? and explain in as much detail as possible what I'm doing wrong? Thank you
I think you have 2 ways to resolve this problem
1: Your input to function login is not correct
login() {
const user = {email: this.email, password: this.password};
this.AppserviceService.login(user).subscribe( data => {
console.log(data);
});
}
Change to
login() {
this.AppserviceService.login(email: this.email, password: this.password).subscribe( data => {
console.log(data);
});
}
2: Change the function login
login ( email: string, password: string ){
const body = {email,password}
return this.http.post <AppsResp>("http://apitest.e-bango.com/api/auth/login" , body );
}
to
login ( {email: string, password: string }){
const body = {email,password}
return this.http.post <AppsResp>("http://apitest.e-bango.com/api/auth/login" , body );
}
just change login method in appserviceService
login ( body ){
return this.http.post <AppsResp>("http://apitest.e-bango.com/api/auth/login" , body );
}
its because your .login from AppserviceService is accepts or excepts 2 arguments, this is email and password. But you gonna put there user object
try this
export class LoginComponent {
email:string ='';
password:string='';
constructor(public AppserviceService: AppserviceService) { }
login() {
this.AppserviceService.login(this.email, this.password).subscribe( data => {
console.log(data);
});
}
}
Please check destructuring in the docs
login ({email, password}){
...
}
You can also give values by defect
login ({email="",password=""}){
...
}
And you can indicate the type
login(({email="",password=""}:{email?:string,password?:string}){
...
}
If you use "optional parameters" use ? to indicate is optional
BTW: you can pass the user itself
login(user:{email?:string,password?:string}){
return this.http.post(...,user);
}
Below is my Component :
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { HttpService } from './http.service';
import { ProjectidService } from './projectid.service';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
projectDetailForm: FormGroup;
public submitted = false;
constructor(private fb: FormBuilder, private projectidvalidator: ProjectidService) { }
ngOnInit() {
this.projectDetailForm = this.fb.group({
projectid: ['', [Validators.required], [this.projectidvalidator.validate.bind(this.projectidvalidator)]],
projectname: ['name', Validators.required]
})
}
get f() { return this.projectDetailForm.controls; }
get validprojectid() { return this.projectDetailForm.get('projectid'); }
onSubmit(form: FormGroup) {
this.submitted = true;
// stop here if form is invalid
if (this.projectDetailForm.invalid) {
return;
}
console.log('Valid?', this.projectDetailForm.valid); // true or false
console.log('ID', this.projectDetailForm.value.projectid);
console.log('Name', this.projectDetailForm.value.projectname);
}
}
My Service :
import { Injectable } from '#angular/core';
import { Observable, of } from 'rxjs';
import { delay, tap, debounceTime } from 'rxjs/operators';
#Injectable()
export class HttpService {
constructor() { }
checkProjectID(id): Observable<any> {
// Here I will have valid HTTP service call to check the data
return of(true)
}
}
My Async validator :
import { HttpService } from './http.service';
import { Injectable } from '#angular/core';
import { AsyncValidator, AbstractControl, ValidationErrors } from '#angular/forms';
import { Observable, of } from 'rxjs';
import { map, catchError, debounceTime, switchMap } from 'rxjs/operators';
#Injectable()
export class ProjectidService {
constructor(private _httpService:HttpService) { }
validate(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
console.log(control.value);
return control.valueChanges.pipe(
debounceTime(500),
switchMap(_ => this._httpService.checkProjectID(control.value).pipe(
map(isTaken => {
console.log(isTaken);
if (isTaken) {
return { noproject: true }
} else {
return null
}
})
)),
catchError(() => null)
);
}
}
and template :
<form [formGroup]="projectDetailForm" name="projectdetails" (ngSubmit)="onSubmit(projectDetailForm)">
<div class="form-group">
<label for="id">Project ID</label>
<input type="text" class="form-control" id="id" [ngClass]="{ 'is-invalid': f.projectid.invalid && (f.projectid.dirty || f.projectid.touched) }" placeholder="Project ID" name="projectid" formControlName='projectid'>
<button type="button">Validate</button>
<div *ngIf="f.projectid.invalid && (f.projectid.dirty || f.projectid.touched)" class="invalid-feedback">
<div *ngIf="f.projectid.errors.required">Project ID is required</div>
<div *ngIf="f.projectid.errors?.noproject">
Project id is not valid
</div>
</div>
<div *ngIf="f.projectid.errors?.noproject">
Project id is not valid
</div>
{{f.projectid.errors | json}}
</div>
<div class="form-group">
<label for="name">Project Name</label>
<input type="text" class="form-control" id="name" placeholder="Project Name" name="projectname" readonly formControlName='projectname'>
</div>
<div class="form-group d-flex justify-content-end">
<div class="">
<button type="button" class="btn btn-primary">Cancel</button>
<button type="submit" class="btn btn-primary ml-1">Next</button>
</div>
</div>
</form>
Problem is my custom async validation error message is not getting displayed.
Here is stackblitz example
You could do it as follows using rxjs/timer:
import { timer } from "rxjs";
....
return timer(500).pipe(
switchMap(() => {
if (!control.value) {
return of(null);
}
return this._httpService.checkProjectID(control.value).pipe(
map(isTaken => {
console.log(isTaken);
if (isTaken) {
return { noproject: true };
} else {
return null;
}
})
);
})
);
Sample
The real problem is and I have encountered this myself, you subscribe to the value change but you need to wait for the statuschange to return.
It is "PENDING" while it is doing the call.
The debounce/timer/... are just 'hacks' since you never know when the value is returned.
Declare a variable:
this.formValueAndStatusSubscription: Subscription;
In your
this.formValueAndStatusSubscription =
combineLatest([this.form.valueChanges, this.form.statusChanges]).subscribe(
() => this.formStatusBaseOnValueAndStatusChanges = this.form.status
);
Don't forget to desstroy the subscription
The most important point in the async validation is as descriped in Angular Doc
The observable returned must be finite, meaning it must complete at
some point. To convert an infinite observable into a finite one, pipe
the observable through a filtering operator such as first, last, take,
or takeUntil.
so basically you can use for example take(1) , it'll take the first emission then mark the Observable completed
return control.valueChanges.pipe(
debounceTime(500),
take(1),
switchMap(() =>
this._httpService.checkProjectID(control.value).pipe(
map(isTaken =>
isTaken ? { noproject: true } : null
)
))
)
demo
I have api end point which save data to the database, post/comments/
when I test it in postman everything works perfect. but in front end data are saved but only id , the data I want to save from form input author and comment.
here is what is saved in database after a user submit the form inputs:
{
"_id": {
"$oid": "5b26c65ffecfe0047846677d"
},
"author": null,
"description": null
}
Here is component.ts :
import { Component, OnInit} from '#angular/core';
import { MoviesService } from '../movies.service';
import { RouterModule, Routes } from '#angular/router';
import {ActivatedRoute} from '#angular/router';
#Component({
selector: 'app-movie',
templateUrl: './movie.component.html',
styleUrls: ['./movie.component.scss']
})
export class MovieComponent implements OnInit {
movie: object;
review: {};
addreview: any;
addreviews: any[];
constructor(private router: ActivatedRoute, private moviesService: MoviesService) {
this.movie = [];
this.review = [];
this.addreview = [];
this.addreviews = [];
}
addReview(addreview: any): void {
if (!addreview) { return; }
this.moviesService.createReview(addreview)
.then(reviews => {
console.log(reviews);
this.addreviews.push(reviews.addreview);
});
}
ngOnInit() {
this.router.params.subscribe((params) => {
// tslint:disable-next-line:prefer-const
let id = params['id'];
this.moviesService.getMovie(id)
.then(movie => {
this.movie = movie;
});
});
this.router.params.subscribe((params) => {
// tslint:disable-next-line:prefer-const
let id = params['id'];
this.moviesService.getReview(id)
.then(review => {
console.log(review);
this.review = review;
});
});
}
}
Here is service.ts
export class MoviesService {
searchStr: string;
queryUrl = '/search/';
theatreUrl = '/theatre/';
moveUrl = '/movies/';
reviewUrl = '/comments/';
private apiUrl = 'http://localhost:8000';
constructor(private http: Http, private _jsonp: Jsonp) { }
createReview(review: string): Promise<any> {
return this.http.post(this.apiUrl + this.reviewUrl, review)
.toPromise()
.then(this.handleData)
.catch(this.handleError);
}
private handleData(res: any) {
const body = res.json();
console.log(body); // for development purposes only
return body.result || body || {};
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for development purposes only
return Promise.reject(error.message || error);
}
}
compo.html
<form (ngSubmit)="addReview(addreview)">
<div class="form-group movie-username">
<label for="author">Name:</label>
<input type="text" class="form-control movie-username_text" id="usr" [(ngModel)]="addreview.author" name="author">
</div>
<div class="form-group movie-textarea">
<label for="movie-textarea_label description">Do you like the movie? leave us a comment below</label>
<textarea class="form-control rounded-0"
id="movie-textarea_textarea" #description="ngModel" rows="10"
[(ngModel)]="addreview.description"
name="description"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Submitted data are not saved to the database what is wrong with my code? any help will be apreciated, thanks
I am working on Firebase authentication with angular 4. I am trying to display the error messages but it is showing on the second click. In the console, it shows the error on the first click, but when I bind it to HTML component it shows the click on the second click. I am using the following auth service.
import { Injectable } from '#angular/core';
import { AngularFireDatabaseModule, AngularFireDatabase } from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth';
import { Router } from "#angular/router";
import * as firebase from 'firebase';
#Injectable()
export class AuthService {
authState: any = null;
isLoggedIn: any;
error: any;
constructor(private afAuth: AngularFireAuth,
private db: AngularFireDatabase,
private router:Router) {
this.afAuth.authState.subscribe((auth) => {
this.authState = auth
});
}
// Returns true if user is logged in
get authenticated(): boolean {
return this.authState !== null;
}
// Returns current user data
get currentUser(): any {
return this.authenticated ? this.authState : null;
}
// Returns
get currentUserObservable(): any {
return this.afAuth.authState
}
// Returns current user UID
get currentUserId(): string {
return this.authenticated ? this.authState.uid : '';
}
emailLogin(email:string, password:string) {
return this.afAuth.auth.signInWithEmailAndPassword(email, password)
.then((user) => {
this.router.navigate(['/dashboard_home'])
this.isLoggedIn = this.authenticated;
})
.catch(error => {
this.error = error;
console.log(error)
});
}
// Sends email allowing user to reset password
resetPassword(email: string) {
var auth = firebase.auth();
return auth.sendPasswordResetEmail(email)
.then(() => console.log("email sent"))
.catch((error) => console.log(error))
}
//// Sign Out ////
signOut(): void {
this.afAuth.auth.signOut();
this.router.navigate(['/administrator'])
}
//// Helpers ////
private updateUserData(): void {
// Writes user name and email to realtime db
// useful if your app displays information about users or for admin features
let path = `users/${this.currentUserId}`; // Endpoint on firebase
let data = {
email: this.authState.email,
name: this.authState.displayName
}
this.db.object(path).update(data)
.catch(error => console.log(error));
}
}
My login.html page looks like that.
<div class="card-block">
<div class="alert alert-danger" role="alert" *ngIf="error">{{ error }}</div>
<form autocomplete="off" id="loginAdmin" (submit)="loginAdmin($event)">
<div class="row">
<div class="col-md-4 mx-auto">
<mat-form-field>
<input type="text" id="username" name="username" matInput placeholder="Användarnamn">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-md-4 mx-auto">
<mat-form-field>
<input type="password" id="password" name="password" matInput placeholder="Lösenord">
</mat-form-field>
</div>
</div>
<div class="row"></div>
<div class="row">
<div class="col-md-12 text-center">
<button type="submit" mat-raised-button>Logga in</button>
</div>
</div>
</form>
</div>
and my component.ts for login page is given
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../services/auth/auth.service';
import {Router} from "#angular/router";
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
error = '';
constructor(private authService: AuthService, private router: Router) { }
ngOnInit() {
}
loginAdmin(e) {
e.preventDefault();
var email = e.target.elements[0].value;
var password = e.target.elements[1].value;
if(email && password) {
var responses = this.authService.emailLogin(email, password);
this.error = this.authService.error;
}
}
}
If you use the above service you can login use. but it shows errors in the console if email and password are not correct, and it is not showing on binding with HTML.
The binding look like that.
<div class="alert alert-danger" role="alert" *ngIf="error">{{ error }}</div>
Now What I want, to send display error on first click as well as to get all the user data logged in.
I fond the solution. This service work for me.
import {AngularFireAuth} from 'angularfire2/auth';
#Injectable()
export class AuthService {
authState: any = null;
constructor(private afAuth: AngularFireAuth, private router: Router) {
this.afAuth.authState.subscribe((auth) => {
this.authState = auth
});
}
get isUserAnonymousLoggedIn(): boolean {
return (this.authState !== null) ? this.authState.isAnonymous : false
}
get currentUserId(): string {
return (this.authState !== null) ? this.authState.uid : ''
}
get currentUserName(): string {
return this.authState['email']
}
get currentUser(): any {
return (this.authState !== null) ? this.authState : null;
}
get isUserEmailLoggedIn(): boolean {
if ((this.authState !== null) && (!this.isUserAnonymousLoggedIn)) {
return true
} else {
return false
}
}
signUpWithEmail(email: string, password: string) {
return this.afAuth.auth.createUserWithEmailAndPassword(email, password)
.then((user) => {
this.authState = user
})
.catch(error => {
console.log(error)
throw error
});
}
loginWithEmail(email: string, password: string) {
return this.afAuth.auth.signInWithEmailAndPassword(email, password)
.then((user) => {
this.authState = user
})
.catch(error => {
console.log(error)
throw error
});
}
signOut(): void {
this.afAuth.auth.signOut();
this.router.navigate(['/'])
}
}
For more detail visit Angular 4 Firebase Auth – Email/Password Authentication with AngularFire2 v4
I am trying to display an alert after a user is registered. I have tried debugging and understood that it is going to error function always ( When a user is registered successfully and a user already exists).
Below is my code. I am not able to understood why is it always going into error.
Any help is appreciated since I am stuck with this from long time. Thanks in advance.
1)Alert Component
import { AlertService } from './../../shared/services/alert.service';
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-alert',
templateUrl: './alert.component.html',
styleUrls: ['./alert.component.css']
})
export class AlertComponent {
private _alertService;
private message: any;
constructor(alertService: AlertService) {
this._alertService = alertService;
}
ngOnInit() {
this._alertService.getMessage().subscribe(message => { this.message = message; });
}
}
2.Alert Template
<div *ngIf="message" [ngClass]="{ 'alert': message, 'alert-success': message.type === 'success',
'alert-danger': message.type === 'error' }">{{message.text}}</div>
3)Register Template
<div class="container">
<h2>Register</h2>
<form name="form" (ngSubmit)="f.form.valid && register()" #f="ngForm" novalidate>
<div class="form-group" [ngClass]="{ 'has-error': f.submitted && !username.valid }">
<label for="username">Username</label>
<input type="text" class="form-control" name="username" [(ngModel)]="model.username" #username="ngModel" required />
<div *ngIf="f.submitted && !username.valid" class="help-block">Username is required</div>
</div>
<div class="form-group" [ngClass]="{ 'has-error': f.submitted && !password.valid }">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" [(ngModel)]="model.password" #password="ngModel" required minlength="10" />
<div *ngIf="f.submitted && !password.valid" class="help-block"> Password is required (minimum 10 characters)</div>
</div>
<div class="form-group">
<button class="btn btn-primary" (click)="registerUser()">Register</button>
<app-alert></app-alert>
<a [routerLink]="['']" class="btn btn-link">Cancel</a>
</div>
</form>
</div>
4)Register Component
import { AlertService } from './../../shared/services/alert.service';
import { RegisterService } from './../../shared/services/register.service';
import { Observable } from 'rxjs/Observable';
import { Component, OnInit } from '#angular/core';
import { Router, ActivatedRoute } from '#angular/router';
import { AuthService } from '../../shared/services/index';
import { Http, Request, RequestMethod, RequestOptions, Headers, Response } from '#angular/http';
#Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
private _authService: AuthService;
private _alertService: AlertService;
private _regsiterService: RegisterService;
private appContent = 'application/json';
private _router: Router;
private baseUrl = 'http://localhost:5000/api/v1/';
model: any = {};
username: string;
password: string;
constructor(authService: AuthService, http: Http, router: Router, registerService: RegisterService, alertService: AlertService) {
this._authService = authService;
this._regsiterService = registerService;
this._router = router;
this._alertService = alertService;
}
ngOnInit() {
}
registerUser() {
this._regsiterService.registerUser(this.model.username, this.model.password)
.subscribe(
data => {
console.log('Calling alert');
this._alertService.success('Registration Successful');
this._router.navigate(['/login']);
},
error => {
console.log('Calling alert');
// this._alertService.error(error);
});
}
}
5)Alert Service
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
#Injectable()
// Checks if a user is a authenticated user and has the valid token without expiration.
export class AlertService {
private subject = new Subject<any>();
success(message: string) {
console.log('Registration Successful');
this.subject.next({ type: 'success', text: message });
}
// error(message: string) {
// console.log('Registration Failed');
// this.subject.next({ type: 'error', text: message });
// }
getMessage(): Observable<any> { return this.subject.asObservable(); }
}
Below is the Error Screenshot
In your html you have:
(ngSubmit)="f.form.valid && register()"
But your method is:
registerUser() {
// ..
}
So the angular parser cannot find the register method that is defined in your html.
Unexpected end of json input
This error normally happens when you have a http call that gets failed for whatever reason ( wrong url, server is down, port is closed, ) and the returned response from the server is not a JSON.
Have a look at your network tab and see the http cal that you're making, what is that you're getting in the response tab.
Basically this error generally means, Javascript hasn't been able to parse something that it was meant to be JSON
If I were you I would check for typos in the template and ts file.
Also, you can try to just import the services at the top of the file and just add them in the constructor like this :
constructor(private authService: AuthService, private http: Http, private router: Router, private registerService: RegisterService, private alertService: AlertService) { }
I think TS will do the assignment for you.
Then onInit() or any other place you can write this.authService.someMethod() etc.
For sure the "not a function" error indicates misspelling/typo.
As it is mentioned already register() exist in your html template but not in the ts file. I would rename the properties of the RegisterComponent also to make sure that possible typos and bugs would be avoided in the future.
The Unexpected end of json input might be due to the fact that you are not providing a valid json from your server.
I haven't seen the code inside this._regsiterService.registerUser . But I believe there's a response.json() call that causes the issue.