Hello there,
I’m having troubles to use a custom provider AuthService (which uses another custom provider Api) in app.js
Console logs that odious error “no provider for Api!”
I’ve tried to declare _auth with @ViewChild decorator, as the “sidemenu” template does ( @ViewChild(AuthService) _auth: AuthService ) but then i get this error “TypeError: Cannot read property ‘authenticated’ of undefined” (note that authenticated is a AuthService function) in MyApp’s constructor.
I’m sure it’s a silly noob mistake…
Here’s is the code…
//APP.TS
import { Component, ViewChild } from '@angular/core';
import { App, ionicBootstrap, Platform, Nav, Modal, Menu } from 'ionic-angular';
import { StatusBar } from 'ionic-native';
import {provide} from '@angular/core';
import {Http} from '@angular/http'
import {AuthHttp, AuthConfig} from 'angular2-jwt';
import {Type} from '@angular/core';
import {AuthService} from './providers/auth-serv/auth-serv';
import { Page1 } from './pages/page1/page1';
import { DiscoverPage } from './pages/discover/discover';
import { LoginPage } from './pages/login/login';
@Component({
templateUrl: 'build/app.html',
providers: [
AuthService,
provide(AuthHttp, {
useFactory: (http) => {
return new AuthHttp(new AuthConfig(), http);
},
deps: [Http]
})
]
})
class MyApp {
@ViewChild(Nav) nav: Nav;
@ViewChild(Menu) menu: Menu;
rootPage: any = DiscoverPage;
isLoggined: Boolean = false;
pages: Array<{ title: string, component: any }>
constructor(private platform: Platform, private _auth: AuthService) {
this.initializeApp();
this.isLoggined = this._auth.authenticated();
this.pages = [
{ title: 'Page uno', component: Page1 },
{ title: 'Discover', component: DiscoverPage }
];
}
initializeApp() {
this.platform.ready().then(() => {
StatusBar.styleDefault();
});
}
openLogin() {
this._auth.showLockLogin();
}
openRegister() {
this._auth.showLockRegister();
}
openPage(page) {
this.nav.setRoot(page.component);
}
}
ionicBootstrap(MyApp);
AUTH-SERV.TS
// AUTH-SERV.TS
import { Storage, LocalStorage } from 'ionic-angular';
import { AuthHttp, JwtHelper, tokenNotExpired } from 'angular2-jwt';
import { Injectable, NgZone, Component } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { Api } from '../api/api';
// Avoid name not found warnings
declare var Auth0Lock: any;
@Injectable()
@Component({
providers:[Api]
})
export class AuthService {
jwtHelper: JwtHelper = new JwtHelper();
lock = new Auth0Lock('pEjOdUrwqAycw5ctUHXo5rZ71jS4BcW7', 'petify.eu.auth0.com');
refreshSubscription: any;
user: Object;
zoneImpl: NgZone;
constructor(private authHttp: AuthHttp, zone: NgZone,
private _api: Api, private _storage: Storage) {
this.zoneImpl = zone;
// If there is a profile saved in local storage
this._storage.get('profile').then(profile => {
this.user = JSON.parse(profile);
}).catch(error => {
console.log(error);
});
}
public authenticated() {
// Check if there's an unexpired JWT
return tokenNotExpired();
}
public showLock() {
// Show the Auth0 Lock widget
this.lock.show({
authParams: {
scope: 'openid offline_access',
device: 'Mobile device'
},
connections: ['facebook', 'google-oauth2']
},
(err, profile, token, accessToken, state, refreshToken) => {
if (err) {
alert(err);
}
var user = this.auth02Petify(profile);
});
}
public showLockLogin() {
// Show the Auth0 Lock widget
this.lock.showSignin({
authParams: {
scope: 'openid offline_access',
device: 'Mobile device'
},
connections: ['facebook', 'google-oauth2']
},
(err, profile, token, accessToken, state, refreshToken) => {
if (err) {
alert(err);
}
// If authentication is successful, save the items
// in local storage
console.log(profile);
console.log(state);
var user = this.auth02Petify(profile);
console.log(user);
// this.local.set('profile', JSON.stringify(profile));
// this.local.set('id_token', token);
// this.local.set('refresh_token', refreshToken);
// this.zoneImpl.run(() => this.user = profile);
// // Schedule a token refresh
// this.scheduleRefresh();
});
}
public showLockRegister() {
// Show the Auth0 Lock widget
this.lock.showSignup({
authParams: {
scope: 'openid offline_access',
device: 'Mobile device'
},
connections: ['facebook', 'google-oauth2']
},
(err, profile, token, accessToken, state, refreshToken) => {
if (err) {
alert(err);
}
// If authentication is successful, save the items
// in local storage
let user = this.auth02Petify(profile);
this._api.params = JSON.stringify(user);
this._api.post('register')
.subscribe(
data => {
console.log(data);
this._storage.set('profile', data);
},
error => { console.log(error); })
// this.local.set('profile', JSON.stringify(profile));
// this.local.set('id_token', token);
// this.local.set('refresh_token', refreshToken);
// this.zoneImpl.run(() => this.user = profile);
// // Schedule a token refresh
// this.scheduleRefresh();
});
}
public logout() {
this._storage.remove('profile');
this._storage.remove('id_token');
this._storage.remove('refresh_token');
this.zoneImpl.run(() => this.user = null);
// Unschedule the token refresh
this.unscheduleRefresh();
}
auth02Petify(auth_profile){
let user = {
email : "",
name : "",
type : 0
}
switch (auth_profile.identities[0].connection)
{
case undefined:
alert('invalid connection (_utils.auth02Petify)');
break;
case "facebook":
user.email = auth_profile.email;
user.name = auth_profile.name;
user.type = 2; //google plus
break
case "google-oauth2":
user.email = auth_profile.email;
user.name = auth_profile.name || auth_profile.nick_name;
user.type = 4; //google plus
//@TODO: get country, city, etc
break;
default:
return;
}
return user;
}
}
API.TS
import { Injectable } from '@angular/core';
import { Http , Headers} from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class Api {
private api_host: string;
data: any;
method: string;
params: string;
headers: Headers;
constructor(private http: Http) {
this.data = null;
this.api_host = "http://localhost/petFinder/api";
this.method = "GET";
this.params = null;
this.headers = null;
this.headers = new Headers();
this.headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
}
get(api_method:String) {
return this.http.get(this.api_host+"/"+api_method, {headers: this.headers} )
.map(res => res.json())
}
post(api_method:String) {
return this.http.post(this.api_host+"/"+api_method, this.params, {headers: this.headers} )
.map(res => res.json())
}
}