I am using Angular 2.0.0-beta.15. I am trying to get data from service in a component. Following is the piece of code in component.
import {Component} from 'angular2/core';
import {UserService} from '../services/user.service';
#Component({
selector: 'parent',
templateUrl: './views/parentUser.html',
providers: [UserService]
})
export class ParentUserComponent {
constructor(private _userService:UserService) {
this._userService.getCurrentUser().subscribe(data => console.log(data));
}
}
Now my UserService piece of code is
import {Injectable} from 'angular2/core';
import {Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
#Injectable()
export class UserService {
private currentUser = {
username: '',
role: '',
targetURL: ''
};
setCurrentUser(currentUser) {
this.currentUser.username = currentUser.username;
this.currentUser.role = currentUser.role;
this.currentUser.targetURL = currentUser.targetURL;
console.log('current User:' + JSON.stringify(this.currentUser));
}
getCurrentUser() {
return Observable.of(this.currentUser);
}
}
My boots.ts is as follows:
///<reference path="../../node_modules/angular2/typings/browser.d.ts"/>
import {bootstrap} from 'angular2/platform/browser';
import {provide} from 'angular2/core';
import {ROUTER_PROVIDERS, ROUTER_DIRECTIVES, RouteConfig, Location, LocationStrategy, HashLocationStrategy} from 'angular2/router';
import {AppComponent} from './app.component';
import {HTTP_PROVIDERS} from 'angular2/http';
import {UserService} from './services/user.service';
import 'rxjs/Rx';
bootstrap(AppComponent, [ROUTER_PROVIDERS, HTTP_PROVIDERS, provide(LocationStrategy, {useClass: HashLocationStrategy}), UserService]);
Now when i try to run my component. it throws error like
Error: Uncaught (in promise): No provider for a!
angular2-polyfills.js:528 Unhandled Promise rejection: No provider for a!
NoProviderError {message:"No provider for a!, stack: "Error: DI Exception↵ at NoProviderError.BaseExc…odules/angular2/bundles/angular2.dev.js:11788:19)", keys: Array[3], injectors: Array[3]}
Can somebody guide me?
Related
Im having some issues with validation a jwt in nestjs. Alot of documentation and tutorials show how to create token etc. I just want to validate it and protect graphql resolvers.
In my jwt.strategy.ts i have this code:
import { Injectable } from '#nestjs/common';
import { ConfigService } from '#nestjs/config';
import { PassportStrategy } from '#nestjs/passport';
import { passportJwtSecret } from 'jwks-rsa';
import { ExtractJwt, Strategy } from 'passport-jwt';
#Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private configService: ConfigService) {
super({
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: 'xxxxx',
}),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
audience: 'urn:microsoft:userinfo',
issuer: 'xxxxx',
algorithms: ['RS256'],
});
}
validate(payload: unknown): unknown {
return payload;
}
}
And in my authz module i have:
import { Module } from '#nestjs/common';
import { PassportModule } from '#nestjs/passport';
import { JwtStrategy } from './jwt.strategy';
#Module({
imports: [PassportModule.register({ defaultStrategy: 'jwt' })],
providers: [JwtStrategy],
exports: [PassportModule],
})
export class AuthzModule {}
In my resolvers i use the UseGuards decorator:
#UseGuards(AuthGuard('jwt'))
All this should work, but i get an error:
TypeError: Cannot read properties of undefined (reading 'logIn')
I dont want to do any login, just validate the token.
ANy tips on this? Have tried google, been at it for hours. Thanks!
I have a problem in my Ionic app with AngularJS, in register.page.ts; when i am going to add the AccessProviders path in the project the project says:ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(RegisterPageModule)[AccessProviders -> AccessProviders -> AccessProviders -> AccessProviders]: NullInjectorError: No provider for AccessProviders!
I have created the access providers folder and files manually.
register.page.ts
import {Router} from "#angular/router";
import { ToastController, LoadingController, AlertController } from "#ionic/angular";
import {AccessProviders} from "../../providers/access-providers";
#Component({
selector: 'app-register',
templateUrl: './register.page.html',
styleUrls: ['./register.page.scss'],
})
export class RegisterPage implements OnInit {
name: string = "";
gender: string = "";
dob: string = "";
email: string = "";
password: string = "";
confirm_password: string = "";
disabledButton;
constructor(
private router: Router,
private toastCtrl: ToastController,
private alertCtrl: AlertController,
private loadingCtrl: LoadingController,
private accsPrvds: AccessProviders,
) { }
ionViewDidEnter() {
this.disabledButton = false;
}
access-providers.ts
import { HttpClient, HttpHeaders, HttpErrorResponse } from "#angular/common/http";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/timeout';
#Injectable()
export class AccessProviders {
server: string = 'http://localhost:8100/register'; //should change.
constructor(
public http: HttpClient
) {
}
postData(body, file) {
let headers = new HttpHeaders({
'Content-Type': 'application/json; charset=UTF-8'
});
let options = {
headers: headers
};
return this.http.post(this.server + file, JSON.stringify(body), options)
.timeout(59000)// 59 sec timeout
.map(res => res);
}
}
How i can solve this problem? I hope got my answer.
ADD blow code inside your access-providers.ts file:
import { Injectable } from '#angular/core'; // at top
#Injectable({
providedIn: 'root' // just before your class
})
export class AccessProviders {}
Make sure that HttpClientModule is registered at the level of AppModule
Just add this in your app.module.ts
import { HttpClientModule } from '#angular/common/http'
/////
#NgModule({
imports: [ HttpClientModule ]
})
It looks like you need to add it under providers in your app.modules.ts file.
If you only need the class in one page you could add it to the page.module.ts file of the corresponding page.
I had a similar problem, I found my solution here:
https://github.com/angular/angular/issues/20339#issuecomment-354767429
I had to import
"import {HttpClientModule} from '# angular / common / http';" in
imports: [HttpClientModule], inside the module that references the component.
In your app module
You have to add at the top :
import {AccessProviders} from "../../providers/access-providers";
On the same file, find providers and just add AccessProviders to the list of providers.
I am following How to Dynamically Create a Component in Angular to add components dynamically inside another component. I am receiving a weired error of undefined variable.
My Component file (MessComponent)
<template #messContainer>
<p>
mess works!
</p>
</template>
ts file
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-mess',
templateUrl: './mess.component.html',
styleUrls: ['./mess.component.scss'],
})
export class MessComponent implements OnInit {
constructor() { }
ngOnInit() {}
}
Parent Component (hosting dynamic component)
module ts file
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { CommonModule } from '#angular/common';
import { IonicModule } from '#ionic/angular';
import { FormsModule } from '#angular/forms';
import { HomePage } from './home.page';
import { HomePageRoutingModule } from './home-routing.module';
import { MessComponent } from './../mess/mess.component';
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
HomePageRoutingModule
],
declarations: [HomePage, MessComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
entryComponents: [MessComponent]
})
export class HomePageModule {}
ts file
import { Component, ViewChild, ViewContainerRef, ComponentFactoryResolver, ComponentRef, ComponentFactory, OnInit } from "#angular/core";
import { MessComponent } from "./../mess/mess.component";
#Component({
selector: "app-home",
templateUrl: "home.page.html",
styleUrls: ["home.page.scss"],
})
export class HomePage implements OnInit {
componentRef: any;
#ViewChild('messContainer', { read: ViewContainerRef, static: true }) entry: ViewContainerRef;
createComponent() {
this.entry.clear();
const factory = this.resolver.resolveComponentFactory(MessComponent);
this.componentRef = this.entry.createComponent(factory);
}
destroyComponent() {
this.componentRef.destroy();
}
constructor(private resolver: ComponentFactoryResolver) {}
ngOnInit(): void {
this.createComponent();
}
}
and the error I am receiving
Uncaught (in promise): TypeError: this.entry is undefined
I understand this is claiming regarding the variable entry, but don't understand why it is not identifying that variable. To conclude, why I cannot add the component?
Solved it. Actually I was passing wrong param to the #ViewChild(''). I was passing the template name (container) of the child while I should have passed the container name in the parent component. So created a div in the parent component with #messContainer and corrected the #ViewChild
Important!:
now #messContainer is in the parent component and everything works as expected.
#ViewChild('messContainer', { read: ViewContainerRef, static: true }) entry: ViewContainerRef;
I'm trying to make the canActivate function returns true or false.
The boolean value will come from the function signin() in file login.service.ts
in response.json().message and appear true or false but does not appear the value when I use this.loginService.logado() in canActivate function in file auth.guard.ts.
Anyone know how to solve this problem?
login.service.ts
import {Injectable} from "#angular/core";
import {Http, Headers} from "#angular/http";
import {Observable} from "rxjs/Observable";
import 'rxjs/Rx';
import {Config} from '../config';
#Injectable()
export class LoginService{
token: string;
userId: string;
constructor (private _http: Http) {}
login(contentLogin){
const body = JSON.stringify(contentLogin);
const header = new Headers({'Content-Type': 'application/json'});
return this._http.post(Config.URL_SITE + 'auth/login', body, {headers: header})
.map(response => response.json())
.catch(error => Observable.throw(error.json()));
}
signin() {
this.token = localStorage['token'];
this.userId = localStorage['userId'];
const body = JSON.stringify({token: this.token, userId: this.userId});
const header = new Headers({'Content-Type': 'application/json'});
return this._http.post(Config.URL_SITE + 'auth/signin', body, {headers: header})
.map(response => response.json().message) //true or false
.catch(error => Observable.throw(error.json()));
}
}
auth.guard.ts
import {Injectable} from '#angular/core';
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '#angular/router';
import {Observable} from 'rxjs/Rx';
import {LoginService} from './login/login.service';
#Injectable()
export class AuthGuard implements CanActivate {
constructor(private loginService: LoginService) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
return this.loginService.signin()
}
}
This is a bit a weird behavior of canActivate but it does wait for the observable to complete, instead of just for an event of the observable.
You can workaround using
return this.loginService.signin().first();
Don't forget to import the take operator.
I'm not managing to make the protected component HeaderComponent be redirected to the LoginComponent component if the value is false the function canActivate.
The HeaderComponent component and their children are protected, only accessing the URL http://localhost:3000/#/header/index the screen goes blank, and I wanted it to be directed to http://localhost:3000/#/auth that is the login screen
Anyone know how to help me?
auth.guard.ts
import {Injectable} from '#angular/core';
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from '#angular/router';
import {Observable, BehaviorSubject} from 'rxjs/Rx';
import 'rxjs/operator/take';
import {LoginService} from './login/login.service';
#Injectable()
export class AuthGuard implements CanActivate {
constructor(private loginService: LoginService, private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | boolean {
this.loginService.logado()
.subscribe(
data => {
return data //true
},
error => {
this.loginService.redirectUrl = state.url;
this.router.navigate(['/auth']);
return error //false
}
)
return this.loginService.logado().take(1);
}
}
routes.component.ts
import {Routes, RouterModule} from '#angular/router';
import {LoginComponent} from './login/login.component';
import {HeaderComponent} from './header/header.component';
import {AuthGuard} from './auth.guard';
import {UserComponent} from './user/user.component';
import {IndexComponent} from './index/index.component';
import {UserPasswordComponent} from './user/user.password.component';
export const appRoutes: Routes = [
{path: 'auth', component: LoginComponent},
{path: 'user', component: UserPasswordComponent},
{path: 'header', component: HeaderComponent, canActivate: [AuthGuard],
children: [
{path: 'index', component: IndexComponent},
{path: 'user', component: UserComponent}
]
},
{path: '', redirectTo: 'auth', pathMatch: 'full'},
];
export const routing = RouterModule.forRoot(appRoutes);
It works after the repair auth.guard.ts file, using as reference Angular2 - Extending router and Observable
auth.guard.ts
import {Injectable} from '#angular/core';
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from '#angular/router';
import {Observable} from 'rxjs/Rx';
import {LoginService} from './login/login.service';
#Injectable()
export class AuthGuard implements CanActivate {
constructor(private loginService: LoginService, private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | boolean {
return this.loginService.logado()
.map(
data => {
if (data == false) {
this.router.navigate(['/auth']);
return data;
};
if (data == true) {
return data;
}
},
error => {
this.router.navigate(['/auth']);
return error
}
)
}
}