Login and register is not working in angular8 - angular6

I am trying login and register section using reactiveform method in angular 8 but not working.I am not getting any error but when I click submit or register button getting alert message like this :[object Object]. So I can not find the solution.Login and register process not working.If anyone kown please help me to resolve this issue.
Demo:https://stackblitz.com/edit/angular-7-registration-login-example-rfqlxg?file=app%2Fweb%2F_services%2Fuser.service.ts
user.service.ts:
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[]>(`/users`);
}
getById(id: number) {
return this.http.get(`/users/` + id);
}
register(user: User) {
return this.http.post(`/users/register`, user);
}
update(user: User) {
return this.http.put(`/users/` + user.id, user);
}
delete(id: number) {
return this.http.delete(`/users/` + id);
}
}
authentication.service.ts:
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>(`/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);
}
}

The reason why you are seeing [object Object] is because you are passing the entire HttpErrorResponse which is an object . Your alert component template will display it properly if it is not an object.
you can change login form submit method as follows
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.alertService.error(error.message);
this.loading = false;
});
}
please change register components submit method as follows
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.alertService.error(error.message);
this.loading = false;
});
}
what i did is passed the message field from error response. if you want to have a logic for different http error codes , you can have it here and pass a message string to error method based on the error code. please try if you want to handle by error code
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 => {
if(error.staus === 403){
this.alertService.error("You are not authorized");
}else{
this.alertService.error("Something went wrong");
}
this.loading = false;
});
}
}
if you want to display the error as it is
change the alert compoenent template as follows
<div *ngIf="message" [ngClass]="{ 'alert': message, 'alert-success': message.type === 'success', 'alert-danger': message.type === 'error' }">{{message.text |json}}</div>

Related

How to Parse a Json Data Response from an API call in Ionic v3 and store in localStorage

I want to access array data and store in localStorage.
I made an API call and get a response as below, shown on console
My Api Provider:
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
let apiUrl = 'http://localhost:83/buildit/api';
#Injectable()
export class AuthServiceProvider {
constructor(public http: Http) { }
login(credentials) {
//let headers = new Headers();
return new Promise((resolve, reject) => {
this.http.post(apiUrl + '/login.php', JSON.stringify(credentials))
.subscribe(res => {
resolve(res.json());
}, (err) => {
reject(err);
});
});
}
}
login.ts
doLogin() {
if(this.loginData.LoginID =='' || this.loginData.Password ==''){
let toast = this.toastCtrl.create({
message: "Enter username and password",
duration: 3000,
position: 'bottom',
dismissOnPageChange: true
});
toast.onDidDismiss(() => {
});
toast.present();
}
else if(this.loginData.LoginID!=='' && this.loginData.Password!==''){
this.showLoader();
this.authService.login(this.loginData).then((result) => {
this.data = result.data;
console.log(this.data.loginStatus);
if (this.data.loginStatus == 'Valid') {
localStorage.setItem('loginStatus', this.data.loginStatus);
localStorage.setItem('CustomerName', this.data.CustomerName);
localStorage.setItem('Mobile', this.data.Mobile);
localStorage.setItem('Email', this.data.Email);
localStorage.setItem('CustomerID', this.data.CustomerID);
this.navCtrl.setRoot(MyApp);
this.loading.dismiss();
}
else if (result['msg'] == "Please verify your mobile no. to Login") {
this.navCtrl.push(OtpPage,{
ID : result['data'].CustomerID , Mobile : this.loginData.LoginID,
Email: result['data'].Email
});
this.loading.dismiss();
}
else {
document.getElementById('err-span').style.display = "block";
this.loading.dismiss();
}
}, (err) => {
this.loading.dismiss();
this.presentToast(err);
});
}
}
Console.log(data) shows
{"data":[{
"loginStatus":"Valid",
"CustomerName":"Fagbemi Ayodele",
"Mobile":null,
"Email":"fagbemiayodele48#gmail.com",
"CustomerID":"3"
}]}
I need to parse the JSON data to get individual 'value'
I tried this.data.loginStatus to get the loginStatus but it give null value, likewise for others.
Please, can someone show me how to get the data individual value in ionic 3?
Thanks.
Individual values you can get like this:
data[0]['loginStatus']
localStorage.setItem('loginStatus', data[0]['loginStatus']);
localStorage.getItem('loginStatus');
//Valid
data[0]['CustomerName']
localStorage.setItem('CustomerName', data[0]['CustomerName']);
localStorage.getItem('CustomerName');
//Fagbemi Ayodele
data[0]['Mobile']
localStorage.setItem('Mobile', data[0]['Mobile']);
localStorage.getItem('Mobile');
//null
data[0]['Email']
localStorage.setItem('Email', data[0]['Email']);
localStorage.getItem('Email');
//fagbemiayodele48#gmail.com
data[0]['CustomerID']
localStorage.setItem('CustomerID', data[0]['CustomerID']);
localStorage.getItem('CustomerID');
//3

Firebase not logging user out

I took the logout function from Firebase to logout a user that logs in. I can properly log in but I clearly cannot log out. I have tested this out many times but the log out function simply does not work. Any and all help would be much appreciated. The following is my code:
export class AuthService {
private user: Observable<firebase.User>;
private userDetails: firebase.User = null;
constructor(private _firebaseAuth: AngularFireAuth, private router: Router) {
this.user = _firebaseAuth.authState;
this.user.subscribe(
(user) => {
if (user) {
this.userDetails = user;
console.log(this.userDetails);
}
else {
this.userDetails = null;
}
}
);
}
signInWithGoogle() {
return this._firebaseAuth.auth.signInWithRedirect(
new firebase.auth.GoogleAuthProvider()
)
}
signup(email: string, password: string) {
this._firebaseAuth.auth.createUserWithEmailAndPassword(email, password)
.then(value => {
console.log('Success!', value);
})
.catch(err => {
console.log('Something went wrong:',err.message);
});
}
login(email: string, password: string) {
this._firebaseAuth.auth.signInWithEmailAndPassword(email, password)
.then(value => {
console.log('Nice, it worked!');
})
.catch(err => {
console.log('Something went wrong:',err.message);
});
}
isLoggedIn() {
if (this.userDetails == null ) {
return false;
} else {
return true;
}
}
directToNext() {
if (this.isLoggedIn){
this.router.navigate(['/or-items/1']);
}
}
logout() {
this._firebaseAuth.auth.signOut()
.then((res) => this.router.navigate(['/']));
}
}
Then in the HTML:
<script>
import {AuthService} from' ./../AuthService';
function logout() {
this.authService.logout();
}
function isLoggedIn() {
this.authService.isLoggedIn();
}
</script>
<span>
<button mat-raised-button color="basic" (click)="logout()">
logout
</button>
</span>
I know that the user is not correctly being logged out because the firebase console indicates that the user is still logged in.
Qari, AFAIK the Firebase console does not indicate whether the user is logged in or not. I think what it shows is the last login date.
At least on the Android Firebase SDK, when one requests a signout, there is a callback that can be used to indicate whether the call was successful. To be doubly sure, one can get the current user info again and verify that there is no current user. You may want to try along similar lines.

Angular 6 HttpInterceptor - when getting 401 refresh the token and create the same request

I'm using the HttpInterceptor in Angular 6, and trying to built a refresh token mechanisim:
When httpClient request get's 401 status code (unauthorised) the HttpInterceptor will create a request that will refresh the token, it will update the headers of the first request and call it again with the new token.
The code is working until the stage that I need to recall the original request again with the new token that got from the refresh token request.
This is my code:
export class MyInterceptor implements HttpInterceptor {
constructor(public restService:RestService){}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
tap(event => {
if (event instanceof HttpResponse) {
console.log('succeed');
}
}, error => {
if(error.status==401){
this.restService.refreshToken().subscribe(response => {
this.restService.updateHeaders(response['token']);
const newRequest = request.clone();
return next.handle(newRequest);
});
}
})
)
}
}
You need to do something like below. You also need to make sure the new header will be appended to the request. Not sure where you do it, since it's not in this interceptor. The best part to append it would be in an interceptor. Even this one, in case you're actually doing it in the services.
// if multiple requests fail, do only one refresh request
private readonly refreshToken$ = this.restService
.refreshToken() //the refresh token method could update the token in it's internal state, not sure why the later call to updateHeaders
.pipe(
tap(response => this.restService.updateHeaders(response['token'])),
ignoreElements(),
shareReplay(1)
);
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next
.handle(request)
.pipe(
catchError(error => {
if (error.status === 401) {
return concat(this.refreshToken$, throwError(new RetryRequestError()));
} else {
throw error;
}
}),
retryWhen(error => {
if (error instanceof RetryRequestError) {
// try the request again
return;
}
throw error;
})
);
}
class RetryRequestError extends Error {
constructor() {
super('retry_request');
Object.setPrototypeOf(this, RetryRequestError.prototype);
}
}
I read more about it, and used a code that some one wrote, and I changed it a little bit and modified it, and finnaly it worked for me.
of course that if someone use this code he should modified it.
import { Observable } from 'rxjs';
import { HttpClient } from '#angular/common/http';
import { catchError, switchMap } from 'rxjs/operators';
import { Injectable } from "#angular/core";
import { HttpInterceptor, HttpRequest, HttpHandler, HttpSentEvent, HttpHeaderResponse, HttpProgressEvent, HttpResponse, HttpUserEvent, HttpErrorResponse } from "#angular/common/http";
import { _throw as observableThrowError } from 'rxjs/observable/throw';
import { Router } from "#angular/router";
import { environment } from '../../../environments/environment'
#Injectable()
export class RequestInterceptorService implements HttpInterceptor {
public endPoints;
constructor(public httpClient: HttpClient, public router: Router) { this.endPoints = environment.endPoints; }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
return <any>next.handle(req.clone({ headers: req.headers.set('Cache-Control', 'no-cache').set('Pragma', 'no-cache'), withCredentials: true })).pipe(
catchError(error => {
if (req.url.indexOf('refresh_token_login') != -1 && ((<HttpErrorResponse>error).status) == 401) {//the app created request for getting new token/session and got 401,meaning the refresh token/session also expired
this.router.navigate(['/logout']);
}
else if (((<HttpErrorResponse>error).status) == 401 && (<HttpErrorResponse>error).error.error_code == 401001) { // 401001 meaning that the token is invalid
this.router.navigate(['/logout']);
}
else if (((<HttpErrorResponse>error).status) == 401 && (<HttpErrorResponse>error).error.error_code == 401002) { // 401002 meaning that the token has expired
return this.handle401Error(req, next);
} else {
return observableThrowError(error.error);
}
}));
}
handle401Error(req: HttpRequest<any>, next: HttpHandler) {
return this.refreshToken().pipe(
switchMap((res) => {
if (res.status == 200) {
return next.handle(this.getNewRequest(req));
}else{
return this.logoutUser();
}
}),
catchError(error => {
return next.handle(this.getNewRequest(req));
})
)
}
getNewRequest(req: HttpRequest<any>): HttpRequest<any> {
return req.clone({ headers: req.headers.set('Cache-Control', 'no-cache').set('Pragma', 'no-cache'), withCredentials: true });
}
logoutUser() {
this.router.navigate(['/logout']);
return observableThrowError("");
}
refreshToken() {
return this.httpClient.get(this.endPoints.refreshToken, { observe: 'response' }).pipe(
catchError(error => {
return observableThrowError(error);
}));
}
}

Error: Cannot find module "./../providers/auth-service" [duplicate]

I am trying to create Login/SignUp in ionic angular 3.3.0.
I get the error Cannot find module '../providers/auth-service/auth-service'. in the login.ts file. Please Help!
auth-service.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
/*
Generated class for the AuthServiceProvider provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
export class User {
name: string;
email: string;
constructor(name: string, email: string) {
this.name = name;
this.email = email;
}
}
#Injectable()
export class AuthServiceProvider {
currentUser: User;
public login(credentials) {
if (credentials.email === null || credentials.password === null) {
return Observable.throw("Please insert credentials");
} else {
return Observable.create(observer => {
// At this point make a request to your backend to make a real check!
let access = (credentials.password === "pass" && credentials.email === "email");
this.currentUser = new User('ian', 'ianlikono#gmail.com');
observer.next(access);
observer.complete();
});
}
}
public register(credentials) {
if (credentials.email === null || credentials.password === null) {
return Observable.throw("Please insert credentials");
} else {
// At this point store the credentials to your backend!
return Observable.create(observer => {
observer.next(true);
observer.complete();
});
}
}
public getUserInfo() : User {
return this.currentUser;
}
public logout() {
return Observable.create(observer => {
this.currentUser = null;
observer.next(true);
observer.complete();
});
}
}
login.ts
import { Component } from '#angular/core';
import { NavController, AlertController, LoadingController, Loading, IonicPage } from 'ionic-angular';
import { AuthServiceProvider } from '../providers/auth-service/auth-service';
#IonicPage()
#Component({
selector: 'page-login',
templateUrl: 'login.html',
})
export class LoginPage {
loading: Loading;
registerCredentials = { email: '', password: '' };
constructor(private nav: NavController, private auth: AuthServiceProvider, private alertCtrl: AlertController, private loadingCtrl: LoadingController) { }
public createAccount() {
this.nav.push('RegisterPage');
}
public login() {
this.showLoading()
this.auth.login(this.registerCredentials).subscribe(allowed => {
if (allowed) {
this.nav.setRoot('HomePage');
} else {
this.showError("Access Denied");
}
},
error => {
this.showError(error);
});
}
showLoading() {
this.loading = this.loadingCtrl.create({
content: 'Please wait...',
dismissOnPageChange: true
});
this.loading.present();
}
showError(text) {
this.loading.dismiss();
let alert = this.alertCtrl.create({
title: 'Fail',
subTitle: text,
buttons: ['OK']
});
alert.present(prompt);
}
}
ScreenShot Program structure:
From your project structure, your login.ts is inside login folder, and login folder is inside pages folder.
So in order to reach providers folder, you need to write
'../../providers/auth-service/auth-service'
This should move you out of two folders which should solve the issue.
If you are using VS Code, install the plugin called "Typescript Hero" and "Typescript Toolbox", will help you with your imports.
Actually "Typescript Toolbox" shows a lightbulb when you focus your cursor on an imported element and you can select from the lightbulb the import. Very usefull.

localStorage.getItem gives null while I see the item in my storage stack - Angular 4

I use localStorage to store my auth token in it.
After setting item in storage I could not fetch it again! It's while I can see the item in my browser local storage stack.
Also, when I fetch and console the item exactly after set, It's Ok and the console logs my item.
Note:
All my doing is just for user authentications and so on in an Angular 4 SPA. when I want to check my token in a component's constructor, gives me null!
Update:
Here is the code that I use:
in AuthService.ts after getting token:
localStorage.setItem('currentUser', itemData);
and it's the hole AuthService.ts
import {Injectable} from '#angular/core';
import {Http, Response} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
#Injectable()
export class AuthService {
public token: string;
public userRole: number;
constructor(private http: Http) {
this.initCurrentUser();
}
initCurrentUser() {
const currentUser = JSON.parse(localStorage.getItem('currrentUser'));
this.token = currentUser && currentUser.token;
this.userRole = currentUser && currentUser.role;
}
isAuthenticated(): boolean {
return !!this.token;
}
logout(): void {
this.token = null;
this.userRole = null;
localStorage.removeItem('currentUser');
}
login(email: string, password: string): Observable<boolean> {
return this.http.post('http://localhost:8000/api/login',
{email: email, password: password})
.map((response: Response) => {
try {
let token = response.json() && response.json().token;
if (token) {
this.token = token;
let itemData= JSON.stringify({email: email, token: token});
localStorage.setItem('currentUser', itemData);
return true;
} else {
return false;
}
} catch (e) {
return false;
}
});
}
}
and finally, in HomeComponent.ts, to check authentication:
constructor(private auth: AuthService) {
auth.initCurrentUser();
console.log('Home', auth.token); // That gives me a null!
}
In every authentication check I had checked token that I had in auth service and I think that was the point.
I put the initCurrentUser() method in ngOnInit instead of constructor. and in every authentication checking I fetch the user data from local storage and process some on it to checking user authentication.
So the below is my final code that solved my problem:
ngOnInit() {
let currentUser = JSON.parse(localStorage.getItem('currrentUser'));
if (currentUser) {
this.token = currentUser.token;
this.userRole = currentUser.role;
} else {
console.log('not get on init!');
}
}
isAuthenticated(): boolean {
let data = localStorage.getItem('currentUser');
this.token = JSON.parse(data) && JSON.parse(data).token;
this.userRole = JSON.parse(data) && JSON.parse(data).role;
return !!this.token;
}
In my case, I mistakenly placed the key instead of value. Make sure you pass them in a correct order:
localStorage.setItem('key','value');